//===-- 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, Constant *Kind, Constant *Val) {
LLVMContextImpl *pImpl = Context.pImpl;
FoldingSetNodeID ID;
ID.AddPointer(Kind);
if (Val) ID.AddPointer(Val);
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 = (!Val) ?
new AttributeImpl(Context, Kind) :
new AttributeImpl(Context, Kind, Val);
pImpl->AttrsSet.InsertNode(PA, InsertPoint);
}
// Return the AttributesList that we found or created.
return Attribute(PA);
}
Attribute Attribute::get(LLVMContext &Context, AttrKind Kind, Constant *Val) {
ConstantInt *KindVal = ConstantInt::get(Type::getInt64Ty(Context), Kind);
return get(Context, KindVal, Val);
}
Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
assert(Align <= 0x40000000 && "Alignment too large.");
return get(Context, Alignment,
ConstantInt::get(Type::getInt64Ty(Context), Align));
}
Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
uint64_t Align) {
assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
assert(Align <= 0x100 && "Alignment too large.");
return get(Context, StackAlignment,
ConstantInt::get(Type::getInt64Ty(Context), Align));
}
//===----------------------------------------------------------------------===//
// Attribute Accessor Methods
//===----------------------------------------------------------------------===//
bool Attribute::hasAttribute(AttrKind Val) const {
return pImpl && pImpl->hasAttribute(Val);
}
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 (!pImpl) return "";
if (hasAttribute(Attribute::AddressSafety))
return "address_safety";
if (hasAttribute(Attribute::AlwaysInline))
return "alwaysinline";
if (hasAttribute(Attribute::ByVal))
return "byval";
if (hasAttribute(Attribute::InlineHint))
return "inlinehint";
if (hasAttribute(Attribute::InReg))
return "inreg";
if (hasAttribute(Attribute::MinSize))
return "minsize";
if (hasAttribute(Attribute::Naked))
return "naked";
if (hasAttribute(Attribute::Nest))
return "nest";
if (hasAttribute(Attribute::NoAlias))
return "noalias";
if (hasAttribute(Attribute::NoCapture))