//===-- Attributes.cpp - Implement AttributesList -------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// \file
// \brief This file implements the Attribute, AttributeImpl, AttrBuilder,
// AttributeSetImpl, and AttributeSet classes.
//
//===----------------------------------------------------------------------===//
#include "llvm/IR/Attributes.h"
#include "AttributeImpl.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
//===----------------------------------------------------------------------===//
// Attribute Construction Methods
//===----------------------------------------------------------------------===//
Attribute Attribute::get(LLVMContext &Context, AttrKind Kind) {
AttrBuilder B;
return Attribute::get(Context, B.addAttribute(Kind));
}
Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) {
// If there are no attributes, return an empty Attribute class.
if (!B.hasAttributes())
return Attribute();
// Otherwise, build a key to look up the existing attributes.
LLVMContextImpl *pImpl = Context.pImpl;
FoldingSetNodeID ID;
ConstantInt *CI = ConstantInt::get(Type::getInt64Ty(Context), B.Raw());
ID.AddPointer(CI);
void *InsertPoint;
AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
if (!PA) {
// If we didn't find any existing attributes of the same shape then create a
// new one and insert it.
PA = new AttributeImpl(Context, CI);
pImpl->AttrsSet.InsertNode(PA, InsertPoint);
}
// Return the AttributesList that we found or created.
return Attribute(PA);
}
Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
AttrBuilder B;
return get(Context, B.addAlignmentAttr(Align));
}
Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
uint64_t Align) {
AttrBuilder B;
return get(Context, B.addStackAlignmentAttr(Align));
}
//===----------------------------------------------------------------------===//
// Attribute Accessor Methods
//===----------------------------------------------------------------------===//
bool Attribute::hasAttribute(AttrKind Val) const {
return pImpl && pImpl->hasAttribute(Val);
}
bool Attribute::hasAttributes() const {
return pImpl && pImpl->hasAttributes();
}
Constant *Attribute::getAttributeKind() const {
return pImpl ? pImpl->getAttributeKind() : 0;
}
ArrayRef<Constant*> Attribute::getAttributeValues() const {
return pImpl ? pImpl->getAttributeValues() : ArrayRef<Constant*>();
}
/// This returns the alignment field of an attribute as a byte alignment value.
unsigned Attribute::getAlignment() const {
if (!hasAttribute(Attribute::Alignment))
return 0;
return pImpl->getAlignment();
}
/// This returns the stack alignment field of an attribute as a byte alignment
/// value.
unsigned Attribute::getStackAlignment() const {
if (!hasAttribute(Attribute::StackAlignment))
return 0;
return pImpl->getStackAlignment();
}
std::string Attribute::getAsString() const {
if (hasAttribute(Attribute::ZExt))
return "zeroext";
if (hasAttribute(Attribute::SExt))
return "signext";
if (hasAttribute(Attribute::NoReturn))
return "noreturn";
if (hasAttribute(Attribute::NoUnwind))
return "nounwind";
if (hasAttribute(Attribute::UWTable))
return "uwtable";
if (hasAttribute(Attribute::ReturnsTwice))
return "returns_twice";
if (hasAttribute(Attribute::InReg))
return "inreg";
if (hasAttribute(Attribute::NoAlias))
return "noalias";
if (hasAttribute(Attribute::NoCapture))
return "nocapture";
if (hasAttribute(Attribute::StructRet))
return "sret";
if (hasAttribute(Attribute::ByVal))
return "byval";
if (hasAttribute(Attribute::Nest))
return "nest";
if (hasAttribute(Attribute::ReadNone))
return "readnone";
if (hasAttribute(Attribute::ReadOnly))
return "readonly";
if (hasAttribute(Attribute::OptimizeForSize))
return "optsize";
if (hasAttribute(Attribute::NoInline))
return "noinline";
if (hasAttribute