1249259Sdim//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim///
10249259Sdim/// \file
11249259Sdim/// \brief This file contains the simple types necessary to represent the
12249259Sdim/// attributes associated with functions and their calls.
13249259Sdim///
14249259Sdim//===----------------------------------------------------------------------===//
15249259Sdim
16249259Sdim#ifndef LLVM_IR_ATTRIBUTES_H
17249259Sdim#define LLVM_IR_ATTRIBUTES_H
18249259Sdim
19249259Sdim#include "llvm/ADT/ArrayRef.h"
20249259Sdim#include "llvm/ADT/FoldingSet.h"
21263508Sdim#include "llvm/Support/Compiler.h"
22249259Sdim#include "llvm/Support/PointerLikeTypeTraits.h"
23249259Sdim#include <bitset>
24249259Sdim#include <cassert>
25249259Sdim#include <map>
26249259Sdim#include <string>
27249259Sdim
28249259Sdimnamespace llvm {
29249259Sdim
30249259Sdimclass AttrBuilder;
31249259Sdimclass AttributeImpl;
32249259Sdimclass AttributeSetImpl;
33249259Sdimclass AttributeSetNode;
34249259Sdimclass Constant;
35249259Sdimtemplate<typename T> struct DenseMapInfo;
36249259Sdimclass LLVMContext;
37249259Sdimclass Type;
38249259Sdim
39249259Sdim//===----------------------------------------------------------------------===//
40249259Sdim/// \class
41249259Sdim/// \brief Functions, function parameters, and return types can have attributes
42249259Sdim/// to indicate how they should be treated by optimizations and code
43249259Sdim/// generation. This class represents one of those attributes. It's light-weight
44249259Sdim/// and should be passed around by-value.
45249259Sdimclass Attribute {
46249259Sdimpublic:
47249259Sdim  /// This enumeration lists the attributes that can be associated with
48249259Sdim  /// parameters, function results, or the function itself.
49249259Sdim  ///
50249259Sdim  /// Note: The `uwtable' attribute is about the ABI or the user mandating an
51249259Sdim  /// entry in the unwind table. The `nounwind' attribute is about an exception
52249259Sdim  /// passing by the function.
53249259Sdim  ///
54249259Sdim  /// In a theoretical system that uses tables for profiling and SjLj for
55249259Sdim  /// exceptions, they would be fully independent. In a normal system that uses
56249259Sdim  /// tables for both, the semantics are:
57249259Sdim  ///
58249259Sdim  /// nil                = Needs an entry because an exception might pass by.
59249259Sdim  /// nounwind           = No need for an entry
60249259Sdim  /// uwtable            = Needs an entry because the ABI says so and because
61249259Sdim  ///                      an exception might pass by.
62249259Sdim  /// uwtable + nounwind = Needs an entry because the ABI says so.
63249259Sdim
64249259Sdim  enum AttrKind {
65249259Sdim    // IR-Level Attributes
66249259Sdim    None,                  ///< No attributes have been set
67249259Sdim    Alignment,             ///< Alignment of parameter (5 bits)
68249259Sdim                           ///< stored as log2 of alignment with +1 bias
69249259Sdim                           ///< 0 means unaligned (different from align(1))
70249259Sdim    AlwaysInline,          ///< inline=always
71263508Sdim    Builtin,               ///< Callee is recognized as a builtin, despite
72263508Sdim                           ///< nobuiltin attribute on its declaration.
73249259Sdim    ByVal,                 ///< Pass structure by value
74263508Sdim    Cold,                  ///< Marks function as being in a cold path.
75249259Sdim    InlineHint,            ///< Source said inlining was desirable
76249259Sdim    InReg,                 ///< Force argument to be passed in register
77249259Sdim    MinSize,               ///< Function must be optimized for size first
78249259Sdim    Naked,                 ///< Naked function
79249259Sdim    Nest,                  ///< Nested function static chain
80249259Sdim    NoAlias,               ///< Considered to not alias after call
81249259Sdim    NoBuiltin,             ///< Callee isn't recognized as a builtin
82249259Sdim    NoCapture,             ///< Function creates no aliases of pointer
83249259Sdim    NoDuplicate,           ///< Call cannot be duplicated
84249259Sdim    NoImplicitFloat,       ///< Disable implicit floating point insts
85249259Sdim    NoInline,              ///< inline=never
86249259Sdim    NonLazyBind,           ///< Function is called early and/or
87249259Sdim                           ///< often, so lazy binding isn't worthwhile
88249259Sdim    NoRedZone,             ///< Disable redzone
89249259Sdim    NoReturn,              ///< Mark the function as not returning
90249259Sdim    NoUnwind,              ///< Function doesn't unwind stack
91249259Sdim    OptimizeForSize,       ///< opt_size
92263508Sdim    OptimizeNone,          ///< Function must not be optimized.
93249259Sdim    ReadNone,              ///< Function does not access memory
94249259Sdim    ReadOnly,              ///< Function only reads from memory
95251662Sdim    Returned,              ///< Return value is always equal to this argument
96249259Sdim    ReturnsTwice,          ///< Function can return twice
97249259Sdim    SExt,                  ///< Sign extended before/after call
98249259Sdim    StackAlignment,        ///< Alignment of stack for function (3 bits)
99249259Sdim                           ///< stored as log2 of alignment with +1 bias 0
100249259Sdim                           ///< means unaligned (different from
101249259Sdim                           ///< alignstack=(1))
102249259Sdim    StackProtect,          ///< Stack protection.
103249259Sdim    StackProtectReq,       ///< Stack protection required.
104249259Sdim    StackProtectStrong,    ///< Strong Stack protection.
105249259Sdim    StructRet,             ///< Hidden pointer to structure to return
106249259Sdim    SanitizeAddress,       ///< AddressSanitizer is on.
107249259Sdim    SanitizeThread,        ///< ThreadSanitizer is on.
108249259Sdim    SanitizeMemory,        ///< MemorySanitizer is on.
109249259Sdim    UWTable,               ///< Function must be in a unwind table
110249259Sdim    ZExt,                  ///< Zero extended before/after call
111249259Sdim
112249259Sdim    EndAttrKinds           ///< Sentinal value useful for loops
113249259Sdim  };
114249259Sdimprivate:
115249259Sdim  AttributeImpl *pImpl;
116249259Sdim  Attribute(AttributeImpl *A) : pImpl(A) {}
117249259Sdimpublic:
118249259Sdim  Attribute() : pImpl(0) {}
119249259Sdim
120249259Sdim  //===--------------------------------------------------------------------===//
121249259Sdim  // Attribute Construction
122249259Sdim  //===--------------------------------------------------------------------===//
123249259Sdim
124249259Sdim  /// \brief Return a uniquified Attribute object.
125249259Sdim  static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0);
126249259Sdim  static Attribute get(LLVMContext &Context, StringRef Kind,
127249259Sdim                       StringRef Val = StringRef());
128249259Sdim
129249259Sdim  /// \brief Return a uniquified Attribute object that has the specific
130249259Sdim  /// alignment set.
131249259Sdim  static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align);
132249259Sdim  static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align);
133249259Sdim
134249259Sdim  //===--------------------------------------------------------------------===//
135249259Sdim  // Attribute Accessors
136249259Sdim  //===--------------------------------------------------------------------===//
137249259Sdim
138249259Sdim  /// \brief Return true if the attribute is an Attribute::AttrKind type.
139249259Sdim  bool isEnumAttribute() const;
140249259Sdim
141249259Sdim  /// \brief Return true if the attribute is an alignment attribute.
142249259Sdim  bool isAlignAttribute() const;
143249259Sdim
144249259Sdim  /// \brief Return true if the attribute is a string (target-dependent)
145249259Sdim  /// attribute.
146249259Sdim  bool isStringAttribute() const;
147249259Sdim
148249259Sdim  /// \brief Return true if the attribute is present.
149249259Sdim  bool hasAttribute(AttrKind Val) const;
150249259Sdim
151249259Sdim  /// \brief Return true if the target-dependent attribute is present.
152249259Sdim  bool hasAttribute(StringRef Val) const;
153249259Sdim
154249259Sdim  /// \brief Return the attribute's kind as an enum (Attribute::AttrKind). This
155249259Sdim  /// requires the attribute to be an enum or alignment attribute.
156249259Sdim  Attribute::AttrKind getKindAsEnum() const;
157249259Sdim
158249259Sdim  /// \brief Return the attribute's value as an integer. This requires that the
159249259Sdim  /// attribute be an alignment attribute.
160249259Sdim  uint64_t getValueAsInt() const;
161249259Sdim
162249259Sdim  /// \brief Return the attribute's kind as a string. This requires the
163249259Sdim  /// attribute to be a string attribute.
164249259Sdim  StringRef getKindAsString() const;
165249259Sdim
166249259Sdim  /// \brief Return the attribute's value as a string. This requires the
167249259Sdim  /// attribute to be a string attribute.
168249259Sdim  StringRef getValueAsString() const;
169249259Sdim
170249259Sdim  /// \brief Returns the alignment field of an attribute as a byte alignment
171249259Sdim  /// value.
172249259Sdim  unsigned getAlignment() const;
173249259Sdim
174249259Sdim  /// \brief Returns the stack alignment field of an attribute as a byte
175249259Sdim  /// alignment value.
176249259Sdim  unsigned getStackAlignment() const;
177249259Sdim
178249259Sdim  /// \brief The Attribute is converted to a string of equivalent mnemonic. This
179249259Sdim  /// is, presumably, for writing out the mnemonics for the assembly writer.
180249259Sdim  std::string getAsString(bool InAttrGrp = false) const;
181249259Sdim
182249259Sdim  /// \brief Equality and non-equality operators.
183249259Sdim  bool operator==(Attribute A) const { return pImpl == A.pImpl; }
184249259Sdim  bool operator!=(Attribute A) const { return pImpl != A.pImpl; }
185249259Sdim
186249259Sdim  /// \brief Less-than operator. Useful for sorting the attributes list.
187249259Sdim  bool operator<(Attribute A) const;
188249259Sdim
189249259Sdim  void Profile(FoldingSetNodeID &ID) const {
190249259Sdim    ID.AddPointer(pImpl);
191249259Sdim  }
192249259Sdim};
193249259Sdim
194249259Sdim//===----------------------------------------------------------------------===//
195249259Sdim/// \class
196249259Sdim/// \brief This class holds the attributes for a function, its return value, and
197249259Sdim/// its parameters. You access the attributes for each of them via an index into
198249259Sdim/// the AttributeSet object. The function attributes are at index
199249259Sdim/// `AttributeSet::FunctionIndex', the return value is at index
200249259Sdim/// `AttributeSet::ReturnIndex', and the attributes for the parameters start at
201249259Sdim/// index `1'.
202249259Sdimclass AttributeSet {
203249259Sdimpublic:
204263508Sdim  enum AttrIndex LLVM_ENUM_INT_TYPE(unsigned) {
205249259Sdim    ReturnIndex = 0U,
206249259Sdim    FunctionIndex = ~0U
207249259Sdim  };
208249259Sdimprivate:
209249259Sdim  friend class AttrBuilder;
210249259Sdim  friend class AttributeSetImpl;
211249259Sdim  template <typename Ty> friend struct DenseMapInfo;
212249259Sdim
213249259Sdim  /// \brief The attributes that we are managing. This can be null to represent
214249259Sdim  /// the empty attributes list.
215249259Sdim  AttributeSetImpl *pImpl;
216249259Sdim
217249259Sdim  /// \brief The attributes for the specified index are returned.
218251662Sdim  AttributeSetNode *getAttributes(unsigned Index) const;
219249259Sdim
220249259Sdim  /// \brief Create an AttributeSet with the specified parameters in it.
221249259Sdim  static AttributeSet get(LLVMContext &C,
222249259Sdim                          ArrayRef<std::pair<unsigned, Attribute> > Attrs);
223249259Sdim  static AttributeSet get(LLVMContext &C,
224249259Sdim                          ArrayRef<std::pair<unsigned,
225249259Sdim                                             AttributeSetNode*> > Attrs);
226249259Sdim
227249259Sdim  static AttributeSet getImpl(LLVMContext &C,
228249259Sdim                              ArrayRef<std::pair<unsigned,
229249259Sdim                                                 AttributeSetNode*> > Attrs);
230249259Sdim
231249259Sdim
232249259Sdim  explicit AttributeSet(AttributeSetImpl *LI) : pImpl(LI) {}
233249259Sdimpublic:
234249259Sdim  AttributeSet() : pImpl(0) {}
235249259Sdim
236249259Sdim  //===--------------------------------------------------------------------===//
237249259Sdim  // AttributeSet Construction and Mutation
238249259Sdim  //===--------------------------------------------------------------------===//
239249259Sdim
240249259Sdim  /// \brief Return an AttributeSet with the specified parameters in it.
241249259Sdim  static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
242251662Sdim  static AttributeSet get(LLVMContext &C, unsigned Index,
243249259Sdim                          ArrayRef<Attribute::AttrKind> Kind);
244251662Sdim  static AttributeSet get(LLVMContext &C, unsigned Index, AttrBuilder &B);
245249259Sdim
246249259Sdim  /// \brief Add an attribute to the attribute set at the given index. Since
247249259Sdim  /// attribute sets are immutable, this returns a new set.
248251662Sdim  AttributeSet addAttribute(LLVMContext &C, unsigned Index,
249249259Sdim                            Attribute::AttrKind Attr) const;
250249259Sdim
251249259Sdim  /// \brief Add an attribute to the attribute set at the given index. Since
252249259Sdim  /// attribute sets are immutable, this returns a new set.
253251662Sdim  AttributeSet addAttribute(LLVMContext &C, unsigned Index,
254249259Sdim                            StringRef Kind) const;
255263508Sdim  AttributeSet addAttribute(LLVMContext &C, unsigned Index,
256263508Sdim                            StringRef Kind, StringRef Value) const;
257249259Sdim
258249259Sdim  /// \brief Add attributes to the attribute set at the given index. Since
259249259Sdim  /// attribute sets are immutable, this returns a new set.
260251662Sdim  AttributeSet addAttributes(LLVMContext &C, unsigned Index,
261249259Sdim                             AttributeSet Attrs) const;
262249259Sdim
263249259Sdim  /// \brief Remove the specified attribute at the specified index from this
264249259Sdim  /// attribute list. Since attribute lists are immutable, this returns the new
265249259Sdim  /// list.
266251662Sdim  AttributeSet removeAttribute(LLVMContext &C, unsigned Index,
267249259Sdim                               Attribute::AttrKind Attr) const;
268249259Sdim
269249259Sdim  /// \brief Remove the specified attributes at the specified index from this
270249259Sdim  /// attribute list. Since attribute lists are immutable, this returns the new
271249259Sdim  /// list.
272251662Sdim  AttributeSet removeAttributes(LLVMContext &C, unsigned Index,
273249259Sdim                                AttributeSet Attrs) const;
274249259Sdim
275249259Sdim  //===--------------------------------------------------------------------===//
276249259Sdim  // AttributeSet Accessors
277249259Sdim  //===--------------------------------------------------------------------===//
278249259Sdim
279249259Sdim  /// \brief Retrieve the LLVM context.
280249259Sdim  LLVMContext &getContext() const;
281249259Sdim
282249259Sdim  /// \brief The attributes for the specified index are returned.
283251662Sdim  AttributeSet getParamAttributes(unsigned Index) const;
284249259Sdim
285249259Sdim  /// \brief The attributes for the ret value are returned.
286249259Sdim  AttributeSet getRetAttributes() const;
287249259Sdim
288249259Sdim  /// \brief The function attributes are returned.
289249259Sdim  AttributeSet getFnAttributes() const;
290249259Sdim
291249259Sdim  /// \brief Return true if the attribute exists at the given index.
292249259Sdim  bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
293249259Sdim
294249259Sdim  /// \brief Return true if the attribute exists at the given index.
295249259Sdim  bool hasAttribute(unsigned Index, StringRef Kind) const;
296249259Sdim
297249259Sdim  /// \brief Return true if attribute exists at the given index.
298249259Sdim  bool hasAttributes(unsigned Index) const;
299249259Sdim
300249259Sdim  /// \brief Return true if the specified attribute is set for at least one
301249259Sdim  /// parameter or for the return value.
302249259Sdim  bool hasAttrSomewhere(Attribute::AttrKind Attr) const;
303249259Sdim
304249259Sdim  /// \brief Return the attribute object that exists at the given index.
305249259Sdim  Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const;
306249259Sdim
307249259Sdim  /// \brief Return the attribute object that exists at the given index.
308249259Sdim  Attribute getAttribute(unsigned Index, StringRef Kind) const;
309249259Sdim
310249259Sdim  /// \brief Return the alignment for the specified function parameter.
311251662Sdim  unsigned getParamAlignment(unsigned Index) const;
312249259Sdim
313249259Sdim  /// \brief Get the stack alignment.
314249259Sdim  unsigned getStackAlignment(unsigned Index) const;
315249259Sdim
316249259Sdim  /// \brief Return the attributes at the index as a string.
317249259Sdim  std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
318249259Sdim
319249259Sdim  typedef ArrayRef<Attribute>::iterator iterator;
320249259Sdim
321251662Sdim  iterator begin(unsigned Slot) const;
322251662Sdim  iterator end(unsigned Slot) const;
323249259Sdim
324249259Sdim  /// operator==/!= - Provide equality predicates.
325249259Sdim  bool operator==(const AttributeSet &RHS) const {
326249259Sdim    return pImpl == RHS.pImpl;
327249259Sdim  }
328249259Sdim  bool operator!=(const AttributeSet &RHS) const {
329249259Sdim    return pImpl != RHS.pImpl;
330249259Sdim  }
331249259Sdim
332249259Sdim  //===--------------------------------------------------------------------===//
333249259Sdim  // AttributeSet Introspection
334249259Sdim  //===--------------------------------------------------------------------===//
335249259Sdim
336249259Sdim  // FIXME: Remove this.
337249259Sdim  uint64_t Raw(unsigned Index) const;
338249259Sdim
339249259Sdim  /// \brief Return a raw pointer that uniquely identifies this attribute list.
340249259Sdim  void *getRawPointer() const {
341249259Sdim    return pImpl;
342249259Sdim  }
343249259Sdim
344249259Sdim  /// \brief Return true if there are no attributes.
345249259Sdim  bool isEmpty() const {
346249259Sdim    return getNumSlots() == 0;
347249259Sdim  }
348249259Sdim
349249259Sdim  /// \brief Return the number of slots used in this attribute list.  This is
350249259Sdim  /// the number of arguments that have an attribute set on them (including the
351249259Sdim  /// function itself).
352249259Sdim  unsigned getNumSlots() const;
353249259Sdim
354249259Sdim  /// \brief Return the index for the given slot.
355251662Sdim  unsigned getSlotIndex(unsigned Slot) const;
356249259Sdim
357249259Sdim  /// \brief Return the attributes at the given slot.
358249259Sdim  AttributeSet getSlotAttributes(unsigned Slot) const;
359249259Sdim
360249259Sdim  void dump() const;
361249259Sdim};
362249259Sdim
363249259Sdim//===----------------------------------------------------------------------===//
364249259Sdim/// \class
365249259Sdim/// \brief Provide DenseMapInfo for AttributeSet.
366249259Sdimtemplate<> struct DenseMapInfo<AttributeSet> {
367249259Sdim  static inline AttributeSet getEmptyKey() {
368249259Sdim    uintptr_t Val = static_cast<uintptr_t>(-1);
369249259Sdim    Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
370249259Sdim    return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val));
371249259Sdim  }
372249259Sdim  static inline AttributeSet getTombstoneKey() {
373249259Sdim    uintptr_t Val = static_cast<uintptr_t>(-2);
374249259Sdim    Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
375249259Sdim    return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val));
376249259Sdim  }
377249259Sdim  static unsigned getHashValue(AttributeSet AS) {
378249259Sdim    return (unsigned((uintptr_t)AS.pImpl) >> 4) ^
379249259Sdim           (unsigned((uintptr_t)AS.pImpl) >> 9);
380249259Sdim  }
381249259Sdim  static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
382249259Sdim};
383249259Sdim
384249259Sdim//===----------------------------------------------------------------------===//
385249259Sdim/// \class
386249259Sdim/// \brief This class is used in conjunction with the Attribute::get method to
387249259Sdim/// create an Attribute object. The object itself is uniquified. The Builder's
388249259Sdim/// value, however, is not. So this can be used as a quick way to test for
389249259Sdim/// equality, presence of attributes, etc.
390249259Sdimclass AttrBuilder {
391249259Sdim  std::bitset<Attribute::EndAttrKinds> Attrs;
392249259Sdim  std::map<std::string, std::string> TargetDepAttrs;
393249259Sdim  uint64_t Alignment;
394249259Sdim  uint64_t StackAlignment;
395249259Sdimpublic:
396249259Sdim  AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0) {}
397249259Sdim  explicit AttrBuilder(uint64_t Val)
398249259Sdim    : Attrs(0), Alignment(0), StackAlignment(0) {
399249259Sdim    addRawValue(Val);
400249259Sdim  }
401249259Sdim  AttrBuilder(const Attribute &A) : Attrs(0), Alignment(0), StackAlignment(0) {
402249259Sdim    addAttribute(A);
403249259Sdim  }
404249259Sdim  AttrBuilder(AttributeSet AS, unsigned Idx);
405249259Sdim  AttrBuilder(const AttrBuilder &B)
406249259Sdim    : Attrs(B.Attrs),
407249259Sdim      TargetDepAttrs(B.TargetDepAttrs.begin(), B.TargetDepAttrs.end()),
408249259Sdim      Alignment(B.Alignment), StackAlignment(B.StackAlignment) {}
409249259Sdim
410249259Sdim  void clear();
411249259Sdim
412249259Sdim  /// \brief Add an attribute to the builder.
413249259Sdim  AttrBuilder &addAttribute(Attribute::AttrKind Val);
414249259Sdim
415249259Sdim  /// \brief Add the Attribute object to the builder.
416249259Sdim  AttrBuilder &addAttribute(Attribute A);
417249259Sdim
418249259Sdim  /// \brief Add the target-dependent attribute to the builder.
419249259Sdim  AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef());
420249259Sdim
421249259Sdim  /// \brief Remove an attribute from the builder.
422249259Sdim  AttrBuilder &removeAttribute(Attribute::AttrKind Val);
423249259Sdim
424249259Sdim  /// \brief Remove the attributes from the builder.
425249259Sdim  AttrBuilder &removeAttributes(AttributeSet A, uint64_t Index);
426249259Sdim
427249259Sdim  /// \brief Remove the target-dependent attribute to the builder.
428249259Sdim  AttrBuilder &removeAttribute(StringRef A);
429249259Sdim
430249259Sdim  /// \brief Add the attributes from the builder.
431249259Sdim  AttrBuilder &merge(const AttrBuilder &B);
432249259Sdim
433249259Sdim  /// \brief Return true if the builder has the specified attribute.
434249259Sdim  bool contains(Attribute::AttrKind A) const {
435249259Sdim    assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
436249259Sdim    return Attrs[A];
437249259Sdim  }
438249259Sdim
439249259Sdim  /// \brief Return true if the builder has the specified target-dependent
440249259Sdim  /// attribute.
441249259Sdim  bool contains(StringRef A) const;
442249259Sdim
443249259Sdim  /// \brief Return true if the builder has IR-level attributes.
444249259Sdim  bool hasAttributes() const;
445249259Sdim
446249259Sdim  /// \brief Return true if the builder has any attribute that's in the
447249259Sdim  /// specified attribute.
448249259Sdim  bool hasAttributes(AttributeSet A, uint64_t Index) const;
449249259Sdim
450249259Sdim  /// \brief Return true if the builder has an alignment attribute.
451249259Sdim  bool hasAlignmentAttr() const;
452249259Sdim
453249259Sdim  /// \brief Retrieve the alignment attribute, if it exists.
454249259Sdim  uint64_t getAlignment() const { return Alignment; }
455249259Sdim
456249259Sdim  /// \brief Retrieve the stack alignment attribute, if it exists.
457249259Sdim  uint64_t getStackAlignment() const { return StackAlignment; }
458249259Sdim
459249259Sdim  /// \brief This turns an int alignment (which must be a power of 2) into the
460249259Sdim  /// form used internally in Attribute.
461249259Sdim  AttrBuilder &addAlignmentAttr(unsigned Align);
462249259Sdim
463249259Sdim  /// \brief This turns an int stack alignment (which must be a power of 2) into
464249259Sdim  /// the form used internally in Attribute.
465249259Sdim  AttrBuilder &addStackAlignmentAttr(unsigned Align);
466249259Sdim
467249259Sdim  /// \brief Return true if the builder contains no target-independent
468249259Sdim  /// attributes.
469249259Sdim  bool empty() const { return Attrs.none(); }
470249259Sdim
471249259Sdim  // Iterators for target-dependent attributes.
472249259Sdim  typedef std::pair<std::string, std::string>                td_type;
473249259Sdim  typedef std::map<std::string, std::string>::iterator       td_iterator;
474249259Sdim  typedef std::map<std::string, std::string>::const_iterator td_const_iterator;
475249259Sdim
476249259Sdim  td_iterator td_begin()             { return TargetDepAttrs.begin(); }
477249259Sdim  td_iterator td_end()               { return TargetDepAttrs.end(); }
478249259Sdim
479249259Sdim  td_const_iterator td_begin() const { return TargetDepAttrs.begin(); }
480249259Sdim  td_const_iterator td_end() const   { return TargetDepAttrs.end(); }
481249259Sdim
482249259Sdim  bool td_empty() const              { return TargetDepAttrs.empty(); }
483249259Sdim
484249259Sdim  bool operator==(const AttrBuilder &B);
485249259Sdim  bool operator!=(const AttrBuilder &B) {
486249259Sdim    return !(*this == B);
487249259Sdim  }
488249259Sdim
489249259Sdim  // FIXME: Remove this in 4.0.
490249259Sdim
491249259Sdim  /// \brief Add the raw value to the internal representation.
492249259Sdim  AttrBuilder &addRawValue(uint64_t Val);
493249259Sdim};
494249259Sdim
495249259Sdimnamespace AttributeFuncs {
496249259Sdim
497249259Sdim/// \brief Which attributes cannot be applied to a type.
498249259SdimAttributeSet typeIncompatible(Type *Ty, uint64_t Index);
499249259Sdim
500249259Sdim} // end AttributeFuncs namespace
501249259Sdim
502249259Sdim} // end llvm namespace
503249259Sdim
504249259Sdim#endif
505