187e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling//===-- Attributes.cpp - Implement AttributesList -------------------------===//
250ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner//
350ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner//                     The LLVM Compiler Infrastructure
450ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner//
550ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner// This file is distributed under the University of Illinois Open Source
650ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner// License. See LICENSE.TXT for details.
750ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner//
850ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner//===----------------------------------------------------------------------===//
950ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner//
1087e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling// \file
1187e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling// \brief This file implements the Attribute, AttributeImpl, AttrBuilder,
1218e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling// AttributeSetImpl, and AttributeSet classes.
1350ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner//
1450ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner//===----------------------------------------------------------------------===//
1550ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner
160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Attributes.h"
17f6670729aabc1fab85238d2b306a1c1767a807bbBill Wendling#include "AttributeImpl.h"
182c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling#include "LLVMContextImpl.h"
19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/STLExtras.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringExtras.h"
210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h"
221f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Atomic.h"
23ef1894ed7ec56875ee4f8ed0f7498abacc913c06David Greene#include "llvm/Support/Debug.h"
2450ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner#include "llvm/Support/ManagedStatic.h"
25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Mutex.h"
26cfa6ec92e61a1ab040c2b79db5de3a39df732ff6Benjamin Kramer#include "llvm/Support/raw_ostream.h"
273467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling#include <algorithm>
2850ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattnerusing namespace llvm;
2950ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner
3058d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner//===----------------------------------------------------------------------===//
31817abdd8b055059e5930a15704b9f52da4236456Bill Wendling// Attribute Construction Methods
3258d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner//===----------------------------------------------------------------------===//
33b0c9b93bb4c591b1cec0491eec34f792cd3cf111Duncan Sands
348c74ecfbddabe89e150abff4fdff0a27108874b9Bill WendlingAttribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
358c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling                         uint64_t Val) {
368e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling  LLVMContextImpl *pImpl = Context.pImpl;
378e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling  FoldingSetNodeID ID;
388c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  ID.AddInteger(Kind);
398c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  if (Val) ID.AddInteger(Val);
408e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling
418e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling  void *InsertPoint;
42f6670729aabc1fab85238d2b306a1c1767a807bbBill Wendling  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
438e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling
448e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling  if (!PA) {
458e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling    // If we didn't find any existing attributes of the same shape then create a
468e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling    // new one and insert it.
47e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    if (!Val)
48e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer      PA = new EnumAttributeImpl(Kind);
49e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    else
50e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer      PA = new AlignAttributeImpl(Kind, Val);
518e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
528e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling  }
538e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling
54ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling  // Return the Attribute that we found or created.
55034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  return Attribute(PA);
568e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling}
578e635dbc78996bc18cf13b4806706cf3529ea646Bill Wendling
588c74ecfbddabe89e150abff4fdff0a27108874b9Bill WendlingAttribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
598c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  LLVMContextImpl *pImpl = Context.pImpl;
608c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  FoldingSetNodeID ID;
618c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  ID.AddString(Kind);
628c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  if (!Val.empty()) ID.AddString(Val);
638c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling
648c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  void *InsertPoint;
658c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
668c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling
678c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  if (!PA) {
688c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling    // If we didn't find any existing attributes of the same shape then create a
698c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling    // new one and insert it.
70e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    PA = new StringAttributeImpl(Kind, Val);
718c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
728c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  }
738c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling
748c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  // Return the Attribute that we found or created.
758c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return Attribute(PA);
76169d5270751597aed4095ead00401a3374906147Bill Wendling}
77169d5270751597aed4095ead00401a3374906147Bill Wendling
78c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill WendlingAttribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
79169d5270751597aed4095ead00401a3374906147Bill Wendling  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
80169d5270751597aed4095ead00401a3374906147Bill Wendling  assert(Align <= 0x40000000 && "Alignment too large.");
818c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return get(Context, Alignment, Align);
82c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling}
83c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling
84c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill WendlingAttribute Attribute::getWithStackAlignment(LLVMContext &Context,
85c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling                                           uint64_t Align) {
86169d5270751597aed4095ead00401a3374906147Bill Wendling  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
87169d5270751597aed4095ead00401a3374906147Bill Wendling  assert(Align <= 0x100 && "Alignment too large.");
888c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return get(Context, StackAlignment, Align);
89c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling}
90c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling
91817abdd8b055059e5930a15704b9f52da4236456Bill Wendling//===----------------------------------------------------------------------===//
92817abdd8b055059e5930a15704b9f52da4236456Bill Wendling// Attribute Accessor Methods
93817abdd8b055059e5930a15704b9f52da4236456Bill Wendling//===----------------------------------------------------------------------===//
94817abdd8b055059e5930a15704b9f52da4236456Bill Wendling
958c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendlingbool Attribute::isEnumAttribute() const {
968c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return pImpl && pImpl->isEnumAttribute();
97e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling}
98e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling
998c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendlingbool Attribute::isAlignAttribute() const {
1008c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return pImpl && pImpl->isAlignAttribute();
1016dc3781d44e56f0addf28b06232a50f3f9e6b1afBill Wendling}
1026dc3781d44e56f0addf28b06232a50f3f9e6b1afBill Wendling
1038c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendlingbool Attribute::isStringAttribute() const {
1048c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return pImpl && pImpl->isStringAttribute();
1058c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling}
1068c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling
1078c74ecfbddabe89e150abff4fdff0a27108874b9Bill WendlingAttribute::AttrKind Attribute::getKindAsEnum() const {
108f245ae5a4a78d5a02b3b9e2dae819077a56d81e7Bill Wendling  if (!pImpl) return None;
1098c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  assert((isEnumAttribute() || isAlignAttribute()) &&
1108c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling         "Invalid attribute type to get the kind as an enum!");
1118c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return pImpl ? pImpl->getKindAsEnum() : None;
1128c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling}
1138c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling
1148c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendlinguint64_t Attribute::getValueAsInt() const {
115f245ae5a4a78d5a02b3b9e2dae819077a56d81e7Bill Wendling  if (!pImpl) return 0;
1168c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  assert(isAlignAttribute() &&
1178c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling         "Expected the attribute to be an alignment attribute!");
1188c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return pImpl ? pImpl->getValueAsInt() : 0;
1198c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling}
1208c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling
1218c74ecfbddabe89e150abff4fdff0a27108874b9Bill WendlingStringRef Attribute::getKindAsString() const {
122f245ae5a4a78d5a02b3b9e2dae819077a56d81e7Bill Wendling  if (!pImpl) return StringRef();
1238c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  assert(isStringAttribute() &&
1248c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling         "Invalid attribute type to get the kind as a string!");
1258c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return pImpl ? pImpl->getKindAsString() : StringRef();
1268c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling}
1278c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling
1288c74ecfbddabe89e150abff4fdff0a27108874b9Bill WendlingStringRef Attribute::getValueAsString() const {
129f245ae5a4a78d5a02b3b9e2dae819077a56d81e7Bill Wendling  if (!pImpl) return StringRef();
1308c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  assert(isStringAttribute() &&
1318c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling         "Invalid attribute type to get the value as a string!");
1328c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return pImpl ? pImpl->getValueAsString() : StringRef();
1338c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling}
1348c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling
13564754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendlingbool Attribute::hasAttribute(AttrKind Kind) const {
13664754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling  return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
13764754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling}
13864754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling
13964754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendlingbool Attribute::hasAttribute(StringRef Kind) const {
14064754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling  if (!isStringAttribute()) return false;
14164754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling  return pImpl && pImpl->hasAttribute(Kind);
1426dc3781d44e56f0addf28b06232a50f3f9e6b1afBill Wendling}
1436dc3781d44e56f0addf28b06232a50f3f9e6b1afBill Wendling
144e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling/// This returns the alignment field of an attribute as a byte alignment value.
145034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendlingunsigned Attribute::getAlignment() const {
1467beee2876795098d2e2f31ecc2ca29fa7640a8ebBill Wendling  assert(hasAttribute(Attribute::Alignment) &&
1477beee2876795098d2e2f31ecc2ca29fa7640a8ebBill Wendling         "Trying to get alignment from non-alignment attribute!");
1488c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return pImpl->getValueAsInt();
149e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling}
150e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling
151e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling/// This returns the stack alignment field of an attribute as a byte alignment
152e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling/// value.
153034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendlingunsigned Attribute::getStackAlignment() const {
1547beee2876795098d2e2f31ecc2ca29fa7640a8ebBill Wendling  assert(hasAttribute(Attribute::StackAlignment) &&
1557beee2876795098d2e2f31ecc2ca29fa7640a8ebBill Wendling         "Trying to get alignment from non-alignment attribute!");
1568c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return pImpl->getValueAsInt();
157e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling}
158e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling
159b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendlingstd::string Attribute::getAsString(bool InAttrGrp) const {
16014292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (!pImpl) return "";
16114292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling
1628eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany  if (hasAttribute(Attribute::SanitizeAddress))
1638eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany    return "sanitize_address";
16414292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::AlwaysInline))
16514292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "alwaysinline";
1662253a2f52f3c46ae75cd05f5885acb987bd1d6b6Michael Gottesman  if (hasAttribute(Attribute::Builtin))
1672253a2f52f3c46ae75cd05f5885acb987bd1d6b6Michael Gottesman    return "builtin";
16814292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::ByVal))
16914292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "byval";
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (hasAttribute(Attribute::InAlloca))
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return "inalloca";
17214292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::InlineHint))
17314292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "inlinehint";
174034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  if (hasAttribute(Attribute::InReg))
175606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return "inreg";
176cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (hasAttribute(Attribute::JumpTable))
177cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return "jumptable";
17814292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::MinSize))
17914292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "minsize";
18014292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::Naked))
18114292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "naked";
18214292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::Nest))
18314292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "nest";
184034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  if (hasAttribute(Attribute::NoAlias))
185606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return "noalias";
186143d46476cdcf5b88b9ee18ebd799e5820a2db0eBill Wendling  if (hasAttribute(Attribute::NoBuiltin))
187143d46476cdcf5b88b9ee18ebd799e5820a2db0eBill Wendling    return "nobuiltin";
188034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  if (hasAttribute(Attribute::NoCapture))
189606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return "nocapture";
19014292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::NoDuplicate))
19114292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "noduplicate";
19214292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::NoImplicitFloat))
19314292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "noimplicitfloat";
19414292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::NoInline))
19514292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "noinline";
19614292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::NonLazyBind))
19714292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "nonlazybind";
198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (hasAttribute(Attribute::NonNull))
199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return "nonnull";
20014292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::NoRedZone))
20114292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "noredzone";
20214292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::NoReturn))
20314292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "noreturn";
20414292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::NoUnwind))
20514292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "nounwind";
2065768bb8d77892926dff0d078b1fb08c14ea791f3Andrea Di Biagio  if (hasAttribute(Attribute::OptimizeNone))
2075768bb8d77892926dff0d078b1fb08c14ea791f3Andrea Di Biagio    return "optnone";
20814292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::OptimizeForSize))
20914292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "optsize";
210034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  if (hasAttribute(Attribute::ReadNone))
211606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return "readnone";
212034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  if (hasAttribute(Attribute::ReadOnly))
213606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return "readonly";
214456ca048af35163b9f52187e92a23ee0a9f059e8Stephen Lin  if (hasAttribute(Attribute::Returned))
215456ca048af35163b9f52187e92a23ee0a9f059e8Stephen Lin    return "returned";
21614292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::ReturnsTwice))
21714292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "returns_twice";
21814292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::SExt))
21914292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "signext";
220034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  if (hasAttribute(Attribute::StackProtect))
221606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return "ssp";
222034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  if (hasAttribute(Attribute::StackProtectReq))
223606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return "sspreq";
224114baee1fa017daefad2339c77b45b9ca3d79a41Bill Wendling  if (hasAttribute(Attribute::StackProtectStrong))
225606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return "sspstrong";
22614292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::StructRet))
22714292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "sret";
2288eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany  if (hasAttribute(Attribute::SanitizeThread))
2298eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany    return "sanitize_thread";
2308eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany  if (hasAttribute(Attribute::SanitizeMemory))
2318eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany    return "sanitize_memory";
23214292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::UWTable))
23314292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "uwtable";
23414292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  if (hasAttribute(Attribute::ZExt))
23514292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    return "zeroext";
23677226a03dca98e6237c1068f2652fe41bea7b687Diego Novillo  if (hasAttribute(Attribute::Cold))
23777226a03dca98e6237c1068f2652fe41bea7b687Diego Novillo    return "cold";
23814292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling
23914292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  // FIXME: These should be output like this:
24014292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  //
24114292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  //   align=4
24214292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  //   alignstack=8
24314292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  //
2448c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  if (hasAttribute(Attribute::Alignment)) {
245606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    std::string Result;
246b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling    Result += "align";
247b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling    Result += (InAttrGrp) ? "=" : " ";
2488c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling    Result += utostr(getValueAsInt());
249606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return Result;
2501e063d14df0f182626ebdd7ac7f32405aa754e03Charles Davis  }
251b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling
2528c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  if (hasAttribute(Attribute::StackAlignment)) {
253606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    std::string Result;
254b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling    Result += "alignstack";
255b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling    if (InAttrGrp) {
256b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling      Result += "=";
257b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling      Result += utostr(getValueAsInt());
258b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling    } else {
259b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling      Result += "(";
260b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling      Result += utostr(getValueAsInt());
261b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling      Result += ")";
262b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling    }
263606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling    return Result;
2646167c3fcda817f9dbfae4d3013bd63a8f909962fDale Johannesen  }
26514292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling
26614292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  // Convert target-dependent attributes to strings of the form:
26714292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  //
26814292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  //   "kind"
26914292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  //   "kind" = "value"
27014292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  //
2718c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  if (isStringAttribute()) {
27214292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling    std::string Result;
2738c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling    Result += '\"' + getKindAsString().str() + '"';
27414292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling
2758c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling    StringRef Val = pImpl->getValueAsString();
2768c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling    if (Val.empty()) return Result;
2775a4041e7282ca1dba93fe1a97c8260c0ef621f5dBill Wendling
278b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling    Result += "=\"" + Val.str() + '"';
2797beee2876795098d2e2f31ecc2ca29fa7640a8ebBill Wendling    return Result;
28014292a6be51ab57ff425ff263d4134fe46d082c4Bill Wendling  }
281606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling
282606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  llvm_unreachable("Unknown attribute");
28350ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner}
28450ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner
285c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingbool Attribute::operator<(Attribute A) const {
286c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  if (!pImpl && !A.pImpl) return false;
287c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  if (!pImpl) return true;
288c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  if (!A.pImpl) return false;
289c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return *pImpl < *A.pImpl;
290f385f4ca1c7c3975779400dc2acf494878a8d6d4Bill Wendling}
291f385f4ca1c7c3975779400dc2acf494878a8d6d4Bill Wendling
29258d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner//===----------------------------------------------------------------------===//
2932c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling// AttributeImpl Definition
2942c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling//===----------------------------------------------------------------------===//
2952c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling
296cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// Pin the vtables to this file.
297b21ab43cfc3fa0dacf5c95f04e58b6d804b59a16Alexey SamsonovAttributeImpl::~AttributeImpl() {}
298354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzkavoid EnumAttributeImpl::anchor() {}
299354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzkavoid AlignAttributeImpl::anchor() {}
300354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzkavoid StringAttributeImpl::anchor() {}
301b21ab43cfc3fa0dacf5c95f04e58b6d804b59a16Alexey Samsonov
3028c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendlingbool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
3038c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  if (isStringAttribute()) return false;
3048c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return getKindAsEnum() == A;
305529ec718ac6844d2b8b60cb668c80dc5d5acf979Bill Wendling}
3063467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
3078c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendlingbool AttributeImpl::hasAttribute(StringRef Kind) const {
3088c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  if (!isStringAttribute()) return false;
3098c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  return getKindAsString() == Kind;
31060507d53e7e8e6b0c537675f68204a93c3033de7Bill Wendling}
311529ec718ac6844d2b8b60cb668c80dc5d5acf979Bill Wendling
3128c74ecfbddabe89e150abff4fdff0a27108874b9Bill WendlingAttribute::AttrKind AttributeImpl::getKindAsEnum() const {
313e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  assert(isEnumAttribute() || isAlignAttribute());
314e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
3158c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling}
3167beee2876795098d2e2f31ecc2ca29fa7640a8ebBill Wendling
3178c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendlinguint64_t AttributeImpl::getValueAsInt() const {
318e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  assert(isAlignAttribute());
319e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  return static_cast<const AlignAttributeImpl *>(this)->getAlignment();
3208c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling}
3213467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
3228c74ecfbddabe89e150abff4fdff0a27108874b9Bill WendlingStringRef AttributeImpl::getKindAsString() const {
323e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  assert(isStringAttribute());
324e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  return static_cast<const StringAttributeImpl *>(this)->getStringKind();
3258c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling}
3263467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
3278c74ecfbddabe89e150abff4fdff0a27108874b9Bill WendlingStringRef AttributeImpl::getValueAsString() const {
328e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  assert(isStringAttribute());
329e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  return static_cast<const StringAttributeImpl *>(this)->getStringValue();
3308c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling}
3313467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
3328c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendlingbool AttributeImpl::operator<(const AttributeImpl &AI) const {
3338c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  // This sorts the attributes with Attribute::AttrKinds coming first (sorted
3348c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  // relative to their enum value) and then strings.
33594328f4ff3d450104f15c9dae437cea80417233dBill Wendling  if (isEnumAttribute()) {
33694328f4ff3d450104f15c9dae437cea80417233dBill Wendling    if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
33794328f4ff3d450104f15c9dae437cea80417233dBill Wendling    if (AI.isAlignAttribute()) return true;
33894328f4ff3d450104f15c9dae437cea80417233dBill Wendling    if (AI.isStringAttribute()) return true;
339a7e4409bb238ec3c5169c25afbb0308ae76d1111Anna Zaks  }
340a7e4409bb238ec3c5169c25afbb0308ae76d1111Anna Zaks
34194328f4ff3d450104f15c9dae437cea80417233dBill Wendling  if (isAlignAttribute()) {
34294328f4ff3d450104f15c9dae437cea80417233dBill Wendling    if (AI.isEnumAttribute()) return false;
34394328f4ff3d450104f15c9dae437cea80417233dBill Wendling    if (AI.isAlignAttribute()) return getValueAsInt() < AI.getValueAsInt();
34494328f4ff3d450104f15c9dae437cea80417233dBill Wendling    if (AI.isStringAttribute()) return true;
3458c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  }
3463467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
34794328f4ff3d450104f15c9dae437cea80417233dBill Wendling  if (AI.isEnumAttribute()) return false;
34894328f4ff3d450104f15c9dae437cea80417233dBill Wendling  if (AI.isAlignAttribute()) return false;
34994328f4ff3d450104f15c9dae437cea80417233dBill Wendling  if (getKindAsString() == AI.getKindAsString())
35094328f4ff3d450104f15c9dae437cea80417233dBill Wendling    return getValueAsString() < AI.getValueAsString();
35194328f4ff3d450104f15c9dae437cea80417233dBill Wendling  return getKindAsString() < AI.getKindAsString();
3523467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling}
3533467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
35460507d53e7e8e6b0c537675f68204a93c3033de7Bill Wendlinguint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
355c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  // FIXME: Remove this.
3566765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling  switch (Val) {
3576f78fbbc630d2b86fb752574f5ad74473f57dfb1Chandler Carruth  case Attribute::EndAttrKinds:
3586f78fbbc630d2b86fb752574f5ad74473f57dfb1Chandler Carruth    llvm_unreachable("Synthetic enumerators which should never get here");
3596f78fbbc630d2b86fb752574f5ad74473f57dfb1Chandler Carruth
360034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::None:            return 0;
361034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::ZExt:            return 1 << 0;
362034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::SExt:            return 1 << 1;
363034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::NoReturn:        return 1 << 2;
364034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::InReg:           return 1 << 3;
365034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::StructRet:       return 1 << 4;
366034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::NoUnwind:        return 1 << 5;
367034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::NoAlias:         return 1 << 6;
368034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::ByVal:           return 1 << 7;
369034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::Nest:            return 1 << 8;
370034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::ReadNone:        return 1 << 9;
371034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::ReadOnly:        return 1 << 10;
372034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::NoInline:        return 1 << 11;
373034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::AlwaysInline:    return 1 << 12;
374034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::OptimizeForSize: return 1 << 13;
375034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::StackProtect:    return 1 << 14;
376034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::StackProtectReq: return 1 << 15;
377034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::Alignment:       return 31 << 16;
378034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::NoCapture:       return 1 << 21;
379034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::NoRedZone:       return 1 << 22;
380034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::NoImplicitFloat: return 1 << 23;
381034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::Naked:           return 1 << 24;
382034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::InlineHint:      return 1 << 25;
383034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::StackAlignment:  return 7 << 26;
384034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::ReturnsTwice:    return 1 << 29;
385034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::UWTable:         return 1 << 30;
386034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::NonLazyBind:     return 1U << 31;
3878eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany  case Attribute::SanitizeAddress: return 1ULL << 32;
388034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  case Attribute::MinSize:         return 1ULL << 33;
38967ae13575900e8efd056672987249fd0adbf5e73James Molloy  case Attribute::NoDuplicate:     return 1ULL << 34;
390114baee1fa017daefad2339c77b45b9ca3d79a41Bill Wendling  case Attribute::StackProtectStrong: return 1ULL << 35;
3918eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany  case Attribute::SanitizeThread:  return 1ULL << 36;
3928eec41fc778e99d42172a7f6de76faa43a6d8847Kostya Serebryany  case Attribute::SanitizeMemory:  return 1ULL << 37;
393d18e0b94bfaad5b8a24fcb45b55d7e031cc94202Bill Wendling  case Attribute::NoBuiltin:       return 1ULL << 38;
394456ca048af35163b9f52187e92a23ee0a9f059e8Stephen Lin  case Attribute::Returned:        return 1ULL << 39;
39577226a03dca98e6237c1068f2652fe41bea7b687Diego Novillo  case Attribute::Cold:            return 1ULL << 40;
3962253a2f52f3c46ae75cd05f5885acb987bd1d6b6Michael Gottesman  case Attribute::Builtin:         return 1ULL << 41;
3975768bb8d77892926dff0d078b1fb08c14ea791f3Andrea Di Biagio  case Attribute::OptimizeNone:    return 1ULL << 42;
39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Attribute::InAlloca:        return 1ULL << 43;
399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Attribute::NonNull:         return 1ULL << 44;
400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case Attribute::JumpTable:       return 1ULL << 45;
401bd2acfab4a4692ce39541f380997945e9bbb14aeBill Wendling  }
402bd2acfab4a4692ce39541f380997945e9bbb14aeBill Wendling  llvm_unreachable("Unsupported attribute type");
4036765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling}
4046765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling
4052c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling//===----------------------------------------------------------------------===//
4063467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling// AttributeSetNode Definition
4073467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling//===----------------------------------------------------------------------===//
4083467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
4093467e30edf63b6d8a8d446186674ba9e4b7885a9Bill WendlingAttributeSetNode *AttributeSetNode::get(LLVMContext &C,
4103467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling                                        ArrayRef<Attribute> Attrs) {
4113467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  if (Attrs.empty())
412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
4133467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
4143467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  // Otherwise, build a key to look up the existing attributes.
4153467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  LLVMContextImpl *pImpl = C.pImpl;
4163467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  FoldingSetNodeID ID;
4173467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
4183467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
419f107e6ca9bbfc82c980c3e8e5c6bf04261b49c90Bill Wendling  array_pod_sort(SortedAttrs.begin(), SortedAttrs.end());
4203467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
4213467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  for (SmallVectorImpl<Attribute>::iterator I = SortedAttrs.begin(),
4223467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling         E = SortedAttrs.end(); I != E; ++I)
4233467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling    I->Profile(ID);
4243467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
4253467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  void *InsertPoint;
4263467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  AttributeSetNode *PA =
4273467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling    pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
4283467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
4293467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  // If we didn't find any existing attributes of the same shape then create a
4303467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  // new one and insert it.
4313467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  if (!PA) {
432e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    // Coallocate entries after the AttributeSetNode itself.
433e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    void *Mem = ::operator new(sizeof(AttributeSetNode) +
434e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer                               sizeof(Attribute) * SortedAttrs.size());
435e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    PA = new (Mem) AttributeSetNode(SortedAttrs);
4363467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling    pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
4373467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  }
4383467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
4393467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  // Return the AttributesListNode that we found or created.
4403467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling  return PA;
4413467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling}
4423467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling
443606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendlingbool AttributeSetNode::hasAttribute(Attribute::AttrKind Kind) const {
444e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  for (iterator I = begin(), E = end(); I != E; ++I)
445eddab1550ee10cce3bb26a26e88529cb19451aa3NAKAMURA Takumi    if (I->hasAttribute(Kind))
446606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling      return true;
447606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  return false;
448606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling}
449606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling
4500e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendlingbool AttributeSetNode::hasAttribute(StringRef Kind) const {
451e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  for (iterator I = begin(), E = end(); I != E; ++I)
4520e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling    if (I->hasAttribute(Kind))
4530e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling      return true;
4540e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling  return false;
4550e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling}
4560e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling
4570e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill WendlingAttribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
458e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  for (iterator I = begin(), E = end(); I != E; ++I)
4590e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling    if (I->hasAttribute(Kind))
4600e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling      return *I;
4610e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling  return Attribute();
4620e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling}
4630e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling
4640e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill WendlingAttribute AttributeSetNode::getAttribute(StringRef Kind) const {
465e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  for (iterator I = begin(), E = end(); I != E; ++I)
4660e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling    if (I->hasAttribute(Kind))
4670e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling      return *I;
4680e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling  return Attribute();
4690e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling}
4700e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling
471606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendlingunsigned AttributeSetNode::getAlignment() const {
472e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  for (iterator I = begin(), E = end(); I != E; ++I)
473eddab1550ee10cce3bb26a26e88529cb19451aa3NAKAMURA Takumi    if (I->hasAttribute(Attribute::Alignment))
474606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling      return I->getAlignment();
475606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  return 0;
476606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling}
477606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling
478606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendlingunsigned AttributeSetNode::getStackAlignment() const {
479e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  for (iterator I = begin(), E = end(); I != E; ++I)
480eddab1550ee10cce3bb26a26e88529cb19451aa3NAKAMURA Takumi    if (I->hasAttribute(Attribute::StackAlignment))
481606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling      return I->getStackAlignment();
482606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  return 0;
483606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling}
484606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling
485aae0298921d946a64385052ce6e678d36f936fb3Rafael Espindolastd::string AttributeSetNode::getAsString(bool InAttrGrp) const {
486e94e4ca5fd94de185a840e9237b3b483f62342a8Benjamin Kramer  std::string Str;
487e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer  for (iterator I = begin(), E = end(); I != E; ++I) {
488e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    if (I != begin())
489aae0298921d946a64385052ce6e678d36f936fb3Rafael Espindola      Str += ' ';
490aae0298921d946a64385052ce6e678d36f936fb3Rafael Espindola    Str += I->getAsString(InAttrGrp);
491606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  }
492606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  return Str;
493606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling}
494606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling
4953467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling//===----------------------------------------------------------------------===//
49618e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling// AttributeSetImpl Definition
49758d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner//===----------------------------------------------------------------------===//
49858d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner
49976f103e02164d27b41bd92a9767c7012482ba31aRafael Espindolauint64_t AttributeSetImpl::Raw(unsigned Index) const {
500d05204aea4977eaec25e96bc7605a7bb9d806fc0Bill Wendling  for (unsigned I = 0, E = getNumAttributes(); I != E; ++I) {
501d05204aea4977eaec25e96bc7605a7bb9d806fc0Bill Wendling    if (getSlotIndex(I) != Index) continue;
502e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    const AttributeSetNode *ASN = getSlotNode(I);
503fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling    uint64_t Mask = 0;
504d05204aea4977eaec25e96bc7605a7bb9d806fc0Bill Wendling
505e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    for (AttributeSetNode::iterator II = ASN->begin(),
506fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling           IE = ASN->end(); II != IE; ++II) {
507fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling      Attribute Attr = *II;
5082153691a8ba35cb2bcf9237557b6cae7e9d8e68dBill Wendling
5092153691a8ba35cb2bcf9237557b6cae7e9d8e68dBill Wendling      // This cannot handle string attributes.
5102153691a8ba35cb2bcf9237557b6cae7e9d8e68dBill Wendling      if (Attr.isStringAttribute()) continue;
5112153691a8ba35cb2bcf9237557b6cae7e9d8e68dBill Wendling
5128c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling      Attribute::AttrKind Kind = Attr.getKindAsEnum();
513fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling
5148c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling      if (Kind == Attribute::Alignment)
515fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling        Mask |= (Log2_32(ASN->getAlignment()) + 1) << 16;
5168c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling      else if (Kind == Attribute::StackAlignment)
517fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling        Mask |= (Log2_32(ASN->getStackAlignment()) + 1) << 26;
518fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling      else
5198c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling        Mask |= AttributeImpl::getAttrMask(Kind);
520fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling    }
521fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling
522fca0ed28c81a505b0b71605e8b59e4bb6daeda0eBill Wendling    return Mask;
523d05204aea4977eaec25e96bc7605a7bb9d806fc0Bill Wendling  }
524d05204aea4977eaec25e96bc7605a7bb9d806fc0Bill Wendling
525d05204aea4977eaec25e96bc7605a7bb9d806fc0Bill Wendling  return 0;
526d05204aea4977eaec25e96bc7605a7bb9d806fc0Bill Wendling}
527d05204aea4977eaec25e96bc7605a7bb9d806fc0Bill Wendling
52840bacacad3dac9eb5202193f685719d0f37d7f4aPeter Collingbournevoid AttributeSetImpl::dump() const {
52940bacacad3dac9eb5202193f685719d0f37d7f4aPeter Collingbourne  AttributeSet(const_cast<AttributeSetImpl *>(this)).dump();
53040bacacad3dac9eb5202193f685719d0f37d7f4aPeter Collingbourne}
53140bacacad3dac9eb5202193f685719d0f37d7f4aPeter Collingbourne
5326a325cc46db9cb0c631ac832474e5df039d04b19Bill Wendling//===----------------------------------------------------------------------===//
533c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling// AttributeSet Construction and Mutation Methods
5346a325cc46db9cb0c631ac832474e5df039d04b19Bill Wendling//===----------------------------------------------------------------------===//
5356a325cc46db9cb0c631ac832474e5df039d04b19Bill Wendling
5368232ece5c1e57efe54342fb35610497d50bf894fBill WendlingAttributeSet
5378232ece5c1e57efe54342fb35610497d50bf894fBill WendlingAttributeSet::getImpl(LLVMContext &C,
5388232ece5c1e57efe54342fb35610497d50bf894fBill Wendling                      ArrayRef<std::pair<unsigned, AttributeSetNode*> > Attrs) {
539c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  LLVMContextImpl *pImpl = C.pImpl;
540c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  FoldingSetNodeID ID;
541c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  AttributeSetImpl::Profile(ID, Attrs);
542778986856c42cdc87d2bae29e4079f772ed9192dBill Wendling
5430976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendling  void *InsertPoint;
5441bbd644301ed4d8a7efd4ceb15f71c56fa914f28Bill Wendling  AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
545778986856c42cdc87d2bae29e4079f772ed9192dBill Wendling
54650ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner  // If we didn't find any existing attributes of the same shape then
54750ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner  // create a new one and insert it.
5480976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendling  if (!PA) {
549e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    // Coallocate entries after the AttributeSetImpl itself.
550e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    void *Mem = ::operator new(sizeof(AttributeSetImpl) +
551e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer                               sizeof(std::pair<unsigned, AttributeSetNode *>) *
552e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer                                   Attrs.size());
553e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    PA = new (Mem) AttributeSetImpl(C, Attrs);
5540976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendling    pImpl->AttrsLists.InsertNode(PA, InsertPoint);
55550ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner  }
556778986856c42cdc87d2bae29e4079f772ed9192dBill Wendling
5570598866c052147c31b808391f58434ce3dbfb838Devang Patel  // Return the AttributesList that we found or created.
55899faa3b4ec6d03ac7808fe4ff3fbf3d04e375502Bill Wendling  return AttributeSet(PA);
55950ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner}
56050ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner
56187e10dfefa94f77937c37b0eb51095540d675cbcBill WendlingAttributeSet AttributeSet::get(LLVMContext &C,
5626bdbf061c353295669b6bfc271b948158602d1bcBill Wendling                               ArrayRef<std::pair<unsigned, Attribute> > Attrs){
56387e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  // If there are no attributes then return a null AttributesList pointer.
56487e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  if (Attrs.empty())
56587e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling    return AttributeSet();
56687e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling
56787e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling#ifndef NDEBUG
56887e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
56987e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling    assert((!i || Attrs[i-1].first <= Attrs[i].first) &&
57087e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling           "Misordered Attributes list!");
5718c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling    assert(!Attrs[i].second.hasAttribute(Attribute::None) &&
57287e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling           "Pointless attribute!");
57387e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  }
57487e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling#endif
57587e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling
5766bdbf061c353295669b6bfc271b948158602d1bcBill Wendling  // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
57787e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  // list.
5786bdbf061c353295669b6bfc271b948158602d1bcBill Wendling  SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrPairVec;
5796bdbf061c353295669b6bfc271b948158602d1bcBill Wendling  for (ArrayRef<std::pair<unsigned, Attribute> >::iterator I = Attrs.begin(),
58087e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling         E = Attrs.end(); I != E; ) {
5816bdbf061c353295669b6bfc271b948158602d1bcBill Wendling    unsigned Index = I->first;
58287e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling    SmallVector<Attribute, 4> AttrVec;
5833ba51cefb75364a17e3a23c54c216035c33e67a6NAKAMURA Takumi    while (I != E && I->first == Index) {
58487e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling      AttrVec.push_back(I->second);
58587e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling      ++I;
58687e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling    }
58787e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling
58887e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling    AttrPairVec.push_back(std::make_pair(Index,
58987e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling                                         AttributeSetNode::get(C, AttrVec)));
59087e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  }
59187e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling
59287e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  return getImpl(C, AttrPairVec);
59387e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling}
59487e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling
59587e10dfefa94f77937c37b0eb51095540d675cbcBill WendlingAttributeSet AttributeSet::get(LLVMContext &C,
5966bdbf061c353295669b6bfc271b948158602d1bcBill Wendling                               ArrayRef<std::pair<unsigned,
59787e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling                                                  AttributeSetNode*> > Attrs) {
59887e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  // If there are no attributes then return a null AttributesList pointer.
59987e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  if (Attrs.empty())
60087e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling    return AttributeSet();
60187e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling
60287e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  return getImpl(C, Attrs);
60387e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling}
60487e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling
605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesAttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               const AttrBuilder &B) {
6073fc4b96b503fa202411317684a2ba02e41e43072Bill Wendling  if (!B.hasAttributes())
6083fc4b96b503fa202411317684a2ba02e41e43072Bill Wendling    return AttributeSet();
6098fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling
61064754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling  // Add target-independent attributes.
6118fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
612c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer  for (Attribute::AttrKind Kind = Attribute::None;
6137c1461252b7ee8b3b5a556993cb7b96d793223b6Benjamin Kramer       Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
614c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer    if (!B.contains(Kind))
615c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer      continue;
616c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer
6178fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling    if (Kind == Attribute::Alignment)
6188a6a7bb6a601061031cddd77129532a3b467300bBill Wendling      Attrs.push_back(std::make_pair(Index, Attribute::
6198fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling                                     getWithAlignment(C, B.getAlignment())));
6208fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling    else if (Kind == Attribute::StackAlignment)
6218a6a7bb6a601061031cddd77129532a3b467300bBill Wendling      Attrs.push_back(std::make_pair(Index, Attribute::
6228fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling                              getWithStackAlignment(C, B.getStackAlignment())));
6238fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling    else
6248a6a7bb6a601061031cddd77129532a3b467300bBill Wendling      Attrs.push_back(std::make_pair(Index, Attribute::get(C, Kind)));
6258fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling  }
6268fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling
62764754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling  // Add target-dependent (string) attributes.
628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const AttrBuilder::td_type &TDA : B.td_attrs())
629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Attrs.push_back(
630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        std::make_pair(Index, Attribute::get(C, TDA.first, TDA.second)));
63164754f499058b5dc748ea6d06a084af0ed539ec4Bill Wendling
6328fbc0c296ef067150f3228e389ae04cf7b3b1992Bill Wendling  return get(C, Attrs);
6331bbd644301ed4d8a7efd4ceb15f71c56fa914f28Bill Wendling}
6341bbd644301ed4d8a7efd4ceb15f71c56fa914f28Bill Wendling
6358a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
63632a57958226e369f964a034da2ce7083a1a34297Bill Wendling                               ArrayRef<Attribute::AttrKind> Kind) {
6376bdbf061c353295669b6bfc271b948158602d1bcBill Wendling  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
63832a57958226e369f964a034da2ce7083a1a34297Bill Wendling  for (ArrayRef<Attribute::AttrKind>::iterator I = Kind.begin(),
63932a57958226e369f964a034da2ce7083a1a34297Bill Wendling         E = Kind.end(); I != E; ++I)
6408a6a7bb6a601061031cddd77129532a3b467300bBill Wendling    Attrs.push_back(std::make_pair(Index, Attribute::get(C, *I)));
64187e10dfefa94f77937c37b0eb51095540d675cbcBill Wendling  return get(C, Attrs);
64228d65722d6f283b327b5815914382077fe9c0ab4Bill Wendling}
64328d65722d6f283b327b5815914382077fe9c0ab4Bill Wendling
6448e47daf2858e980210f3e1f007036b24da342c29Bill WendlingAttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
645c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  if (Attrs.empty()) return AttributeSet();
6467bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne  if (Attrs.size() == 1) return Attrs[0];
647c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
6486bdbf061c353295669b6bfc271b948158602d1bcBill Wendling  SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrNodeVec;
6497bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne  AttributeSetImpl *A0 = Attrs[0].pImpl;
6507bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne  if (A0)
6517bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne    AttrNodeVec.append(A0->getNode(0), A0->getNode(A0->getNumAttributes()));
6527bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne  // Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec
6537bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne  // ordered by index.  Because we know that each list in Attrs is ordered by
6547bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne  // index we only need to merge each successive list in rather than doing a
6557bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne  // full sort.
6567bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne  for (unsigned I = 1, E = Attrs.size(); I != E; ++I) {
657e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    AttributeSetImpl *AS = Attrs[I].pImpl;
658e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    if (!AS) continue;
6597bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne    SmallVector<std::pair<unsigned, AttributeSetNode *>, 8>::iterator
6607bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne      ANVI = AttrNodeVec.begin(), ANVE;
6617bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne    for (const AttributeSetImpl::IndexAttrPair
6627bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne             *AI = AS->getNode(0),
6637bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne             *AE = AS->getNode(AS->getNumAttributes());
6647bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne         AI != AE; ++AI) {
6657bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne      ANVE = AttrNodeVec.end();
6667bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne      while (ANVI != ANVE && ANVI->first <= AI->first)
6677bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne        ++ANVI;
6687bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne      ANVI = AttrNodeVec.insert(ANVI, *AI) + 1;
6697bba9c5c0a5235f585ee4bd3efec29e0982de3f8Peter Collingbourne    }
6708e47daf2858e980210f3e1f007036b24da342c29Bill Wendling  }
6718e47daf2858e980210f3e1f007036b24da342c29Bill Wendling
672c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return getImpl(C, AttrNodeVec);
67350ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner}
67450ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner
6758a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
676defaca00b8087d452df2b783250a48a32658a910Bill Wendling                                        Attribute::AttrKind Attr) const {
6778a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  if (hasAttribute(Index, Attr)) return *this;
6788a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  return addAttributes(C, Index, AttributeSet::get(C, Index, Attr));
679defaca00b8087d452df2b783250a48a32658a910Bill Wendling}
680defaca00b8087d452df2b783250a48a32658a910Bill Wendling
6818a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
6829106f73246168fb30d26fb14085c0b3d81fcd350Reed Kotler                                        StringRef Kind) const {
6839106f73246168fb30d26fb14085c0b3d81fcd350Reed Kotler  llvm::AttrBuilder B;
6849106f73246168fb30d26fb14085c0b3d81fcd350Reed Kotler  B.addAttribute(Kind);
6858a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  return addAttributes(C, Index, AttributeSet::get(C, Index, B));
6869106f73246168fb30d26fb14085c0b3d81fcd350Reed Kotler}
6879106f73246168fb30d26fb14085c0b3d81fcd350Reed Kotler
6889e2ef7780b91d8e01a9ab172f80272fc94f6956bBill WendlingAttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
6899e2ef7780b91d8e01a9ab172f80272fc94f6956bBill Wendling                                        StringRef Kind, StringRef Value) const {
6909e2ef7780b91d8e01a9ab172f80272fc94f6956bBill Wendling  llvm::AttrBuilder B;
6919e2ef7780b91d8e01a9ab172f80272fc94f6956bBill Wendling  B.addAttribute(Kind, Value);
6929e2ef7780b91d8e01a9ab172f80272fc94f6956bBill Wendling  return addAttributes(C, Index, AttributeSet::get(C, Index, B));
6939e2ef7780b91d8e01a9ab172f80272fc94f6956bBill Wendling}
6949e2ef7780b91d8e01a9ab172f80272fc94f6956bBill Wendling
6958a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Index,
696e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling                                         AttributeSet Attrs) const {
69749f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  if (!pImpl) return Attrs;
69849f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  if (!Attrs.pImpl) return *this;
69949f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling
7006167c3fcda817f9dbfae4d3013bd63a8f909962fDale Johannesen#ifndef NDEBUG
70149f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  // FIXME it is not obvious how this should work for alignment. For now, say
70249f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  // we can't change a known alignment.
7038a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  unsigned OldAlign = getParamAlignment(Index);
7048a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  unsigned NewAlign = Attrs.getParamAlignment(Index);
7054aefd6b7d4dadf8109221a89742725c116d8f8e0Anton Korobeynikov  assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
7066167c3fcda817f9dbfae4d3013bd63a8f909962fDale Johannesen         "Attempt to change alignment!");
7076167c3fcda817f9dbfae4d3013bd63a8f909962fDale Johannesen#endif
708778986856c42cdc87d2bae29e4079f772ed9192dBill Wendling
70949f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  // Add the attribute slots before the one we're trying to add.
71049f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  SmallVector<AttributeSet, 4> AttrSet;
71149f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  uint64_t NumAttrs = pImpl->getNumAttributes();
71249f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  AttributeSet AS;
71349f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  uint64_t LastIndex = 0;
71449f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
7158a6a7bb6a601061031cddd77129532a3b467300bBill Wendling    if (getSlotIndex(I) >= Index) {
7168a6a7bb6a601061031cddd77129532a3b467300bBill Wendling      if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
71749f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling      break;
71858d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner    }
71949f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling    LastIndex = I + 1;
72049f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling    AttrSet.push_back(getSlotAttributes(I));
72149f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  }
722778986856c42cdc87d2bae29e4079f772ed9192dBill Wendling
72349f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  // Now add the attribute into the correct slot. There may already be an
72449f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  // AttributeSet there.
7258a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  AttrBuilder B(AS, Index);
726778986856c42cdc87d2bae29e4079f772ed9192dBill Wendling
72749f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I)
7288a6a7bb6a601061031cddd77129532a3b467300bBill Wendling    if (Attrs.getSlotIndex(I) == Index) {
729e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer      for (AttributeSetImpl::iterator II = Attrs.pImpl->begin(I),
73049f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling             IE = Attrs.pImpl->end(I); II != IE; ++II)
73139da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling        B.addAttribute(*II);
73249f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling      break;
73349f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling    }
73449f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling
7358a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  AttrSet.push_back(AttributeSet::get(C, Index, B));
73649f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling
73749f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  // Add the remaining attribute slots.
73849f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
73949f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling    AttrSet.push_back(getSlotAttributes(I));
740778986856c42cdc87d2bae29e4079f772ed9192dBill Wendling
74149f6060f16aec4024d644a6ec4ddd3de9b3e8821Bill Wendling  return get(C, AttrSet);
74250ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner}
74350ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner
7448a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Index,
7458246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling                                           Attribute::AttrKind Attr) const {
7468a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  if (!hasAttribute(Index, Attr)) return *this;
7478a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  return removeAttributes(C, Index, AttributeSet::get(C, Index, Attr));
7488246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling}
7498246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling
7508a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Index,
7518246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling                                            AttributeSet Attrs) const {
75298b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  if (!pImpl) return AttributeSet();
75398b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  if (!Attrs.pImpl) return *this;
7548246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling
7556167c3fcda817f9dbfae4d3013bd63a8f909962fDale Johannesen#ifndef NDEBUG
7566167c3fcda817f9dbfae4d3013bd63a8f909962fDale Johannesen  // FIXME it is not obvious how this should work for alignment.
7576167c3fcda817f9dbfae4d3013bd63a8f909962fDale Johannesen  // For now, say we can't pass in alignment, which no current use does.
7588a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  assert(!Attrs.hasAttribute(Index, Attribute::Alignment) &&
75998b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling         "Attempt to change alignment!");
7606167c3fcda817f9dbfae4d3013bd63a8f909962fDale Johannesen#endif
76198b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling
76298b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  // Add the attribute slots before the one we're trying to add.
76398b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  SmallVector<AttributeSet, 4> AttrSet;
76498b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  uint64_t NumAttrs = pImpl->getNumAttributes();
76598b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  AttributeSet AS;
76698b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  uint64_t LastIndex = 0;
76798b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
7688a6a7bb6a601061031cddd77129532a3b467300bBill Wendling    if (getSlotIndex(I) >= Index) {
7698a6a7bb6a601061031cddd77129532a3b467300bBill Wendling      if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
77098b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling      break;
77198b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling    }
77298b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling    LastIndex = I + 1;
77398b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling    AttrSet.push_back(getSlotAttributes(I));
77498b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  }
77598b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling
776e74365462a39529ae48ef4d34ec76b4543b8ea29Bill Wendling  // Now remove the attribute from the correct slot. There may already be an
77798b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  // AttributeSet there.
7788a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  AttrBuilder B(AS, Index);
77998b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling
78098b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I)
7818a6a7bb6a601061031cddd77129532a3b467300bBill Wendling    if (Attrs.getSlotIndex(I) == Index) {
7828a6a7bb6a601061031cddd77129532a3b467300bBill Wendling      B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Index);
78398b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling      break;
78498b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling    }
78598b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling
7868a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  AttrSet.push_back(AttributeSet::get(C, Index, B));
78798b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling
78898b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  // Add the remaining attribute slots.
78998b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
79098b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling    AttrSet.push_back(getSlotAttributes(I));
79198b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling
79298b92f3bf5770e02498549e24b3db75d5862c173Bill Wendling  return get(C, AttrSet);
79350ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner}
79450ee9ddc8f0633af6cb0a5693a2c706e98f944daChris Lattner
795c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling//===----------------------------------------------------------------------===//
796c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling// AttributeSet Accessor Methods
797c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling//===----------------------------------------------------------------------===//
798c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
79985b3fbecdfe934ac7519a8831c4bd262cba99d12Bill WendlingLLVMContext &AttributeSet::getContext() const {
80085b3fbecdfe934ac7519a8831c4bd262cba99d12Bill Wendling  return pImpl->getContext();
80185b3fbecdfe934ac7519a8831c4bd262cba99d12Bill Wendling}
80285b3fbecdfe934ac7519a8831c4bd262cba99d12Bill Wendling
8038a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSet AttributeSet::getParamAttributes(unsigned Index) const {
8048a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  return pImpl && hasAttributes(Index) ?
805c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    AttributeSet::get(pImpl->getContext(),
806606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling                      ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
8078a6a7bb6a601061031cddd77129532a3b467300bBill Wendling                        std::make_pair(Index, getAttributes(Index)))) :
808c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    AttributeSet();
809c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
810c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
811c22f4aa886443507f8406d30d118fdeeac6a8c6cBill WendlingAttributeSet AttributeSet::getRetAttributes() const {
812c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return pImpl && hasAttributes(ReturnIndex) ?
813c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    AttributeSet::get(pImpl->getContext(),
814606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling                      ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
815c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling                        std::make_pair(ReturnIndex,
816c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling                                       getAttributes(ReturnIndex)))) :
817c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    AttributeSet();
818c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
819c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
820c22f4aa886443507f8406d30d118fdeeac6a8c6cBill WendlingAttributeSet AttributeSet::getFnAttributes() const {
821c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return pImpl && hasAttributes(FunctionIndex) ?
822c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    AttributeSet::get(pImpl->getContext(),
823606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling                      ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
824c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling                        std::make_pair(FunctionIndex,
825c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling                                       getAttributes(FunctionIndex)))) :
826c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    AttributeSet();
827c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
828c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
829c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingbool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{
830606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  AttributeSetNode *ASN = getAttributes(Index);
831606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  return ASN ? ASN->hasAttribute(Kind) : false;
832c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
833c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
8340e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendlingbool AttributeSet::hasAttribute(unsigned Index, StringRef Kind) const {
8350e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling  AttributeSetNode *ASN = getAttributes(Index);
8360e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling  return ASN ? ASN->hasAttribute(Kind) : false;
8370e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling}
8380e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling
839c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingbool AttributeSet::hasAttributes(unsigned Index) const {
840606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  AttributeSetNode *ASN = getAttributes(Index);
841606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  return ASN ? ASN->hasAttributes() : false;
842c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
843c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
844c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling/// \brief Return true if the specified attribute is set for at least one
845c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling/// parameter or for the return value.
846c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingbool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const {
847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!pImpl) return false;
848c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
849c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I)
850e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    for (AttributeSetImpl::iterator II = pImpl->begin(I),
851c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling           IE = pImpl->end(I); II != IE; ++II)
852eddab1550ee10cce3bb26a26e88529cb19451aa3NAKAMURA Takumi      if (II->hasAttribute(Attr))
853c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling        return true;
854c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
855c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return false;
856c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
857c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
8580e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill WendlingAttribute AttributeSet::getAttribute(unsigned Index,
8590e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling                                     Attribute::AttrKind Kind) const {
8600e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling  AttributeSetNode *ASN = getAttributes(Index);
8610e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling  return ASN ? ASN->getAttribute(Kind) : Attribute();
8620e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling}
8630e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling
8640e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill WendlingAttribute AttributeSet::getAttribute(unsigned Index,
8650e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling                                     StringRef Kind) const {
8660e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling  AttributeSetNode *ASN = getAttributes(Index);
8670e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling  return ASN ? ASN->getAttribute(Kind) : Attribute();
8680e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling}
8690e9d5d059c4aa959e9ef4dff011dbd38d45a1016Bill Wendling
870606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendlingunsigned AttributeSet::getParamAlignment(unsigned Index) const {
871606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  AttributeSetNode *ASN = getAttributes(Index);
872606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  return ASN ? ASN->getAlignment() : 0;
873c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
874c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
875c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingunsigned AttributeSet::getStackAlignment(unsigned Index) const {
876606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  AttributeSetNode *ASN = getAttributes(Index);
877606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  return ASN ? ASN->getStackAlignment() : 0;
878c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
879c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
880aae0298921d946a64385052ce6e678d36f936fb3Rafael Espindolastd::string AttributeSet::getAsString(unsigned Index,
881b29ce26ea60f7516c853318ffbfc107fde9ad897Bill Wendling                                      bool InAttrGrp) const {
882606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  AttributeSetNode *ASN = getAttributes(Index);
883aae0298921d946a64385052ce6e678d36f936fb3Rafael Espindola  return ASN ? ASN->getAsString(InAttrGrp) : std::string("");
884c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
885c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
886c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling/// \brief The attributes for the specified index are returned.
8878a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSetNode *AttributeSet::getAttributes(unsigned Index) const {
888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!pImpl) return nullptr;
889c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
890606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  // Loop through to find the attribute node we want.
891606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling  for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I)
8928a6a7bb6a601061031cddd77129532a3b467300bBill Wendling    if (pImpl->getSlotIndex(I) == Index)
893606c8e36dfdd28fc589356addd3e2cbb89a32e4dBill Wendling      return pImpl->getSlotNode(I);
894c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
896c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
897c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
8988a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSet::iterator AttributeSet::begin(unsigned Slot) const {
89916c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling  if (!pImpl)
90016c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling    return ArrayRef<Attribute>().begin();
9018a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  return pImpl->begin(Slot);
90216c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling}
90316c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling
9048a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttributeSet::iterator AttributeSet::end(unsigned Slot) const {
90516c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling  if (!pImpl)
90616c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling    return ArrayRef<Attribute>().end();
9078a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  return pImpl->end(Slot);
90816c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling}
90916c4b3cf2943ae2327752cf3de39769d14cfceceBill Wendling
910c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling//===----------------------------------------------------------------------===//
911c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling// AttributeSet Introspection Methods
912c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling//===----------------------------------------------------------------------===//
913c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
914c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling/// \brief Return the number of slots used in this attribute list.  This is the
915c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling/// number of arguments that have an attribute set on them (including the
916c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling/// function itself).
917c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingunsigned AttributeSet::getNumSlots() const {
918c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return pImpl ? pImpl->getNumAttributes() : 0;
919c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
920c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
92176f103e02164d27b41bd92a9767c7012482ba31aRafael Espindolaunsigned AttributeSet::getSlotIndex(unsigned Slot) const {
922c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  assert(pImpl && Slot < pImpl->getNumAttributes() &&
923c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling         "Slot # out of range!");
924c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return pImpl->getSlotIndex(Slot);
925c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
926c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
927c22f4aa886443507f8406d30d118fdeeac6a8c6cBill WendlingAttributeSet AttributeSet::getSlotAttributes(unsigned Slot) const {
928c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  assert(pImpl && Slot < pImpl->getNumAttributes() &&
929c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling         "Slot # out of range!");
930c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return pImpl->getSlotAttributes(Slot);
931c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
932c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
933c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlinguint64_t AttributeSet::Raw(unsigned Index) const {
934c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  // FIXME: Remove this.
935c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return pImpl ? pImpl->Raw(Index) : 0;
936c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
937c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
93899faa3b4ec6d03ac7808fe4ff3fbf3d04e375502Bill Wendlingvoid AttributeSet::dump() const {
93973bc452bcd63620daefb0a3bc613746af7418076Bill Wendling  dbgs() << "PAL[\n";
940c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
94173bc452bcd63620daefb0a3bc613746af7418076Bill Wendling  for (unsigned i = 0, e = getNumSlots(); i < e; ++i) {
94249716e5d84142d7bd3eeff7304f9bc708bff99d0Bill Wendling    uint64_t Index = getSlotIndex(i);
94349716e5d84142d7bd3eeff7304f9bc708bff99d0Bill Wendling    dbgs() << "  { ";
94449716e5d84142d7bd3eeff7304f9bc708bff99d0Bill Wendling    if (Index == ~0U)
94549716e5d84142d7bd3eeff7304f9bc708bff99d0Bill Wendling      dbgs() << "~0U";
94649716e5d84142d7bd3eeff7304f9bc708bff99d0Bill Wendling    else
94749716e5d84142d7bd3eeff7304f9bc708bff99d0Bill Wendling      dbgs() << Index;
94849716e5d84142d7bd3eeff7304f9bc708bff99d0Bill Wendling    dbgs() << " => " << getAsString(Index) << " }\n";
94958d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner  }
950778986856c42cdc87d2bae29e4079f772ed9192dBill Wendling
951ef1894ed7ec56875ee4f8ed0f7498abacc913c06David Greene  dbgs() << "]\n";
952ad9a9e15595bc9d5ba1ed752caf8572957f77a3dDuncan Sands}
9538e47daf2858e980210f3e1f007036b24da342c29Bill Wendling
9548e47daf2858e980210f3e1f007036b24da342c29Bill Wendling//===----------------------------------------------------------------------===//
955c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling// AttrBuilder Method Implementations
956c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling//===----------------------------------------------------------------------===//
957c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
9588a6a7bb6a601061031cddd77129532a3b467300bBill WendlingAttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index)
959c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer  : Attrs(0), Alignment(0), StackAlignment(0) {
960c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  AttributeSetImpl *pImpl = AS.pImpl;
961c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  if (!pImpl) return;
962c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
963c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) {
9648a6a7bb6a601061031cddd77129532a3b467300bBill Wendling    if (pImpl->getSlotIndex(I) != Index) continue;
965c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
966e22cde01a63c907cb23f425ba4f4f16ede754dbeBenjamin Kramer    for (AttributeSetImpl::iterator II = pImpl->begin(I),
967c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling           IE = pImpl->end(I); II != IE; ++II)
96839da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling      addAttribute(*II);
969c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
970c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    break;
971c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  }
972c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
973c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
974c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingvoid AttrBuilder::clear() {
9753f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer  Attrs.reset();
976c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  Alignment = StackAlignment = 0;
977c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
978c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
979c22f4aa886443507f8406d30d118fdeeac6a8c6cBill WendlingAttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
9803f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
981169d5270751597aed4095ead00401a3374906147Bill Wendling  assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
982169d5270751597aed4095ead00401a3374906147Bill Wendling         "Adding alignment attribute without adding alignment value!");
9833f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer  Attrs[Val] = true;
984c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return *this;
985c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
986c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
98739da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill WendlingAttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
98809ed9101c8c7e93c1d814e75ff906bf904778dbbBill Wendling  if (Attr.isStringAttribute()) {
98909ed9101c8c7e93c1d814e75ff906bf904778dbbBill Wendling    addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
99009ed9101c8c7e93c1d814e75ff906bf904778dbbBill Wendling    return *this;
99109ed9101c8c7e93c1d814e75ff906bf904778dbbBill Wendling  }
99209ed9101c8c7e93c1d814e75ff906bf904778dbbBill Wendling
9938c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  Attribute::AttrKind Kind = Attr.getKindAsEnum();
9943f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer  Attrs[Kind] = true;
995c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
9968c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  if (Kind == Attribute::Alignment)
997c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    Alignment = Attr.getAlignment();
9988c74ecfbddabe89e150abff4fdff0a27108874b9Bill Wendling  else if (Kind == Attribute::StackAlignment)
999c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    StackAlignment = Attr.getStackAlignment();
1000c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return *this;
1001c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
1002c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1003ea59f896a672c2e1ef9f02277bce60257aa60989Bill WendlingAttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1004ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling  TargetDepAttrs[A] = V;
1005ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling  return *this;
1006ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling}
1007ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling
100839da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill WendlingAttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
10093f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
10103f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer  Attrs[Val] = false;
101139da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling
101239da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling  if (Val == Attribute::Alignment)
101339da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling    Alignment = 0;
101439da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling  else if (Val == Attribute::StackAlignment)
101539da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling    StackAlignment = 0;
101639da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling
101739da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling  return *this;
101839da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling}
101939da078977ae98b6bf1c3c76a472ed24f5f2a2d2Bill Wendling
1020e74365462a39529ae48ef4d34ec76b4543b8ea29Bill WendlingAttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) {
10218a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  unsigned Slot = ~0U;
102230d2c76800bc821aff6e224e0bd11d88a793303eBill Wendling  for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
102330d2c76800bc821aff6e224e0bd11d88a793303eBill Wendling    if (A.getSlotIndex(I) == Index) {
10248a6a7bb6a601061031cddd77129532a3b467300bBill Wendling      Slot = I;
102530d2c76800bc821aff6e224e0bd11d88a793303eBill Wendling      break;
102630d2c76800bc821aff6e224e0bd11d88a793303eBill Wendling    }
1027c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
10288a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  assert(Slot != ~0U && "Couldn't find index in AttributeSet!");
1029c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
10308a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) {
103174fe825ca597f56985ab4387baca35948647ec4bBill Wendling    Attribute Attr = *I;
103274fe825ca597f56985ab4387baca35948647ec4bBill Wendling    if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) {
103374fe825ca597f56985ab4387baca35948647ec4bBill Wendling      Attribute::AttrKind Kind = I->getKindAsEnum();
10343f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer      Attrs[Kind] = false;
103530d2c76800bc821aff6e224e0bd11d88a793303eBill Wendling
103674fe825ca597f56985ab4387baca35948647ec4bBill Wendling      if (Kind == Attribute::Alignment)
103774fe825ca597f56985ab4387baca35948647ec4bBill Wendling        Alignment = 0;
103874fe825ca597f56985ab4387baca35948647ec4bBill Wendling      else if (Kind == Attribute::StackAlignment)
103974fe825ca597f56985ab4387baca35948647ec4bBill Wendling        StackAlignment = 0;
104074fe825ca597f56985ab4387baca35948647ec4bBill Wendling    } else {
104174fe825ca597f56985ab4387baca35948647ec4bBill Wendling      assert(Attr.isStringAttribute() && "Invalid attribute type!");
104274fe825ca597f56985ab4387baca35948647ec4bBill Wendling      std::map<std::string, std::string>::iterator
104374fe825ca597f56985ab4387baca35948647ec4bBill Wendling        Iter = TargetDepAttrs.find(Attr.getKindAsString());
104474fe825ca597f56985ab4387baca35948647ec4bBill Wendling      if (Iter != TargetDepAttrs.end())
104574fe825ca597f56985ab4387baca35948647ec4bBill Wendling        TargetDepAttrs.erase(Iter);
104674fe825ca597f56985ab4387baca35948647ec4bBill Wendling    }
1047c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  }
1048c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1049c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return *this;
1050c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
1051c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1052ea59f896a672c2e1ef9f02277bce60257aa60989Bill WendlingAttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1053ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling  std::map<std::string, std::string>::iterator I = TargetDepAttrs.find(A);
1054ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling  if (I != TargetDepAttrs.end())
1055ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling    TargetDepAttrs.erase(I);
1056ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling  return *this;
1057ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling}
1058ea59f896a672c2e1ef9f02277bce60257aa60989Bill Wendling
1059c22f4aa886443507f8406d30d118fdeeac6a8c6cBill WendlingAttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
1060c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  if (Align == 0) return *this;
1061c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1062c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1063c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  assert(Align <= 0x40000000 && "Alignment too large.");
1064c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
10653f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer  Attrs[Attribute::Alignment] = true;
1066c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  Alignment = Align;
1067c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return *this;
1068c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
1069c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1070c22f4aa886443507f8406d30d118fdeeac6a8c6cBill WendlingAttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
1071c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  // Default alignment, allow the target to define how to align it.
1072c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  if (Align == 0) return *this;
1073c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1074c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1075c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  assert(Align <= 0x100 && "Alignment too large.");
1076c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
10773f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer  Attrs[Attribute::StackAlignment] = true;
1078c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  StackAlignment = Align;
1079c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return *this;
1080c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
1081c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
108285df6b43403d3ebf5d80023a85699c6fb254941aBill WendlingAttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
108385df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling  // FIXME: What if both have alignments, but they don't match?!
108485df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling  if (!Alignment)
108585df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling    Alignment = B.Alignment;
108685df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling
108785df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling  if (!StackAlignment)
108885df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling    StackAlignment = B.StackAlignment;
108985df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling
1090c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer  Attrs |= B.Attrs;
109185df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling
109285df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling  for (td_const_iterator I = B.TargetDepAttrs.begin(),
109385df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling         E = B.TargetDepAttrs.end(); I != E; ++I)
109485df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling    TargetDepAttrs[I->first] = I->second;
109585df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling
109685df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling  return *this;
109785df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling}
109885df6b43403d3ebf5d80023a85699c6fb254941aBill Wendling
1099c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendlingbool AttrBuilder::contains(StringRef A) const {
1100c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling  return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1101c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling}
1102c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling
1103c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingbool AttrBuilder::hasAttributes() const {
11043f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer  return !Attrs.none() || !TargetDepAttrs.empty();
1105c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
1106c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1107e74365462a39529ae48ef4d34ec76b4543b8ea29Bill Wendlingbool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const {
11088a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  unsigned Slot = ~0U;
1109bdcbccc710a0528b4abce947782fd502bafb848dBill Wendling  for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
1110bdcbccc710a0528b4abce947782fd502bafb848dBill Wendling    if (A.getSlotIndex(I) == Index) {
11118a6a7bb6a601061031cddd77129532a3b467300bBill Wendling      Slot = I;
1112bdcbccc710a0528b4abce947782fd502bafb848dBill Wendling      break;
1113bdcbccc710a0528b4abce947782fd502bafb848dBill Wendling    }
1114bdcbccc710a0528b4abce947782fd502bafb848dBill Wendling
11158a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  assert(Slot != ~0U && "Couldn't find the index!");
1116bdcbccc710a0528b4abce947782fd502bafb848dBill Wendling
11178a6a7bb6a601061031cddd77129532a3b467300bBill Wendling  for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot);
111874fe825ca597f56985ab4387baca35948647ec4bBill Wendling       I != E; ++I) {
111974fe825ca597f56985ab4387baca35948647ec4bBill Wendling    Attribute Attr = *I;
112074fe825ca597f56985ab4387baca35948647ec4bBill Wendling    if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) {
11213f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer      if (Attrs[I->getKindAsEnum()])
112274fe825ca597f56985ab4387baca35948647ec4bBill Wendling        return true;
112374fe825ca597f56985ab4387baca35948647ec4bBill Wendling    } else {
112474fe825ca597f56985ab4387baca35948647ec4bBill Wendling      assert(Attr.isStringAttribute() && "Invalid attribute kind!");
112574fe825ca597f56985ab4387baca35948647ec4bBill Wendling      return TargetDepAttrs.find(Attr.getKindAsString())!=TargetDepAttrs.end();
112674fe825ca597f56985ab4387baca35948647ec4bBill Wendling    }
112774fe825ca597f56985ab4387baca35948647ec4bBill Wendling  }
1128bdcbccc710a0528b4abce947782fd502bafb848dBill Wendling
1129bdcbccc710a0528b4abce947782fd502bafb848dBill Wendling  return false;
1130c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
1131c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1132c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingbool AttrBuilder::hasAlignmentAttr() const {
1133c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return Alignment != 0;
1134c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
1135c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1136c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendlingbool AttrBuilder::operator==(const AttrBuilder &B) {
1137c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer  if (Attrs != B.Attrs)
1138c835b8c30127d15599de2d614434d39a6cc3ae17Benjamin Kramer    return false;
1139c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling
1140c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling  for (td_const_iterator I = TargetDepAttrs.begin(),
1141c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling         E = TargetDepAttrs.end(); I != E; ++I)
1142c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling    if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1143c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling      return false;
1144c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling
1145c342d9d345acdbd95577c7c6e9ce7d3a1bdb57bfBill Wendling  return Alignment == B.Alignment && StackAlignment == B.StackAlignment;
1146c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
1147c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1148c22f4aa886443507f8406d30d118fdeeac6a8c6cBill WendlingAttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
1149f9271ea159b97e2febedcf095c3c4122cb24d077Bill Wendling  // FIXME: Remove this in 4.0.
11508232ece5c1e57efe54342fb35610497d50bf894fBill Wendling  if (!Val) return *this;
11518232ece5c1e57efe54342fb35610497d50bf894fBill Wendling
1152c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
1153c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling       I = Attribute::AttrKind(I + 1)) {
1154c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) {
11553f213e7b3a6829a154d4e8ceb7d8689b389bd5dcBenjamin Kramer      Attrs[I] = true;
1156c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1157c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling      if (I == Attribute::Alignment)
1158c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling        Alignment = 1ULL << ((A >> 16) - 1);
1159c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling      else if (I == Attribute::StackAlignment)
1160c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling        StackAlignment = 1ULL << ((A >> 26)-1);
1161c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling    }
1162c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  }
1163c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1164c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling  return *this;
1165c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling}
1166c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling
1167c22f4aa886443507f8406d30d118fdeeac6a8c6cBill Wendling//===----------------------------------------------------------------------===//
11688e47daf2858e980210f3e1f007036b24da342c29Bill Wendling// AttributeFuncs Function Defintions
11698e47daf2858e980210f3e1f007036b24da342c29Bill Wendling//===----------------------------------------------------------------------===//
11708e47daf2858e980210f3e1f007036b24da342c29Bill Wendling
11717beee2876795098d2e2f31ecc2ca29fa7640a8ebBill Wendling/// \brief Which attributes cannot be applied to a type.
1172e74365462a39529ae48ef4d34ec76b4543b8ea29Bill WendlingAttributeSet AttributeFuncs::typeIncompatible(Type *Ty, uint64_t Index) {
11738e47daf2858e980210f3e1f007036b24da342c29Bill Wendling  AttrBuilder Incompatible;
11748e47daf2858e980210f3e1f007036b24da342c29Bill Wendling
11758e47daf2858e980210f3e1f007036b24da342c29Bill Wendling  if (!Ty->isIntegerTy())
11768e47daf2858e980210f3e1f007036b24da342c29Bill Wendling    // Attribute that only apply to integers.
11778e47daf2858e980210f3e1f007036b24da342c29Bill Wendling    Incompatible.addAttribute(Attribute::SExt)
11788e47daf2858e980210f3e1f007036b24da342c29Bill Wendling      .addAttribute(Attribute::ZExt);
11798e47daf2858e980210f3e1f007036b24da342c29Bill Wendling
11808e47daf2858e980210f3e1f007036b24da342c29Bill Wendling  if (!Ty->isPointerTy())
11818e47daf2858e980210f3e1f007036b24da342c29Bill Wendling    // Attribute that only apply to pointers.
11828e47daf2858e980210f3e1f007036b24da342c29Bill Wendling    Incompatible.addAttribute(Attribute::ByVal)
11838e47daf2858e980210f3e1f007036b24da342c29Bill Wendling      .addAttribute(Attribute::Nest)
11848e47daf2858e980210f3e1f007036b24da342c29Bill Wendling      .addAttribute(Attribute::NoAlias)
11858e47daf2858e980210f3e1f007036b24da342c29Bill Wendling      .addAttribute(Attribute::NoCapture)
1186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addAttribute(Attribute::NonNull)
1187dc89737bcdbb8f69d8ae7578bdfa904cabcfc5edNick Lewycky      .addAttribute(Attribute::ReadNone)
1188dc89737bcdbb8f69d8ae7578bdfa904cabcfc5edNick Lewycky      .addAttribute(Attribute::ReadOnly)
118936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addAttribute(Attribute::StructRet)
119036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addAttribute(Attribute::InAlloca);
11918e47daf2858e980210f3e1f007036b24da342c29Bill Wendling
1192e74365462a39529ae48ef4d34ec76b4543b8ea29Bill Wendling  return AttributeSet::get(Ty->getContext(), Index, Incompatible);
11938e47daf2858e980210f3e1f007036b24da342c29Bill Wendling}
1194