]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This file contains the simple types necessary to represent the | |
11 | // attributes associated with functions and their calls. | |
12 | // | |
13 | //===----------------------------------------------------------------------===// | |
14 | ||
15 | #ifndef LLVM_ATTRIBUTES_H | |
16 | #define LLVM_ATTRIBUTES_H | |
17 | ||
18 | #include "llvm/Support/MathExtras.h" | |
19 | #include "llvm/ADT/ArrayRef.h" | |
20 | #include <cassert> | |
21 | #include <string> | |
22 | ||
23 | namespace llvm { | |
24 | ||
25 | class LLVMContext; | |
26 | class Type; | |
27 | ||
28 | namespace Attribute { | |
29 | ||
30 | /// We use this proxy POD type to allow constructing Attributes constants using | |
31 | /// initializer lists. Do not use this class directly. | |
32 | struct AttrConst { | |
33 | uint64_t v; | |
34 | AttrConst operator | (const AttrConst Attrs) const { | |
35 | AttrConst Res = {v | Attrs.v}; | |
36 | return Res; | |
37 | } | |
38 | AttrConst operator ~ () const { | |
39 | AttrConst Res = {~v}; | |
40 | return Res; | |
41 | } | |
42 | }; | |
43 | ||
44 | /// Function parameters and results can have attributes to indicate how they | |
45 | /// should be treated by optimizations and code generation. This enumeration | |
46 | /// lists the attributes that can be associated with parameters, function | |
47 | /// results or the function itself. | |
48 | /// @brief Function attributes. | |
49 | ||
50 | /// We declare AttrConst objects that will be used throughout the code and also | |
51 | /// raw uint64_t objects with _i suffix to be used below for other constant | |
52 | /// declarations. This is done to avoid static CTORs and at the same time to | |
53 | /// keep type-safety of Attributes. | |
54 | #define DECLARE_LLVM_ATTRIBUTE(name, value) \ | |
55 | const uint64_t name##_i = value; \ | |
56 | const AttrConst name = {value}; | |
57 | ||
58 | DECLARE_LLVM_ATTRIBUTE(None,0) ///< No attributes have been set | |
59 | DECLARE_LLVM_ATTRIBUTE(ZExt,1<<0) ///< Zero extended before/after call | |
60 | DECLARE_LLVM_ATTRIBUTE(SExt,1<<1) ///< Sign extended before/after call | |
61 | DECLARE_LLVM_ATTRIBUTE(NoReturn,1<<2) ///< Mark the function as not returning | |
62 | DECLARE_LLVM_ATTRIBUTE(InReg,1<<3) ///< Force argument to be passed in register | |
63 | DECLARE_LLVM_ATTRIBUTE(StructRet,1<<4) ///< Hidden pointer to structure to return | |
64 | DECLARE_LLVM_ATTRIBUTE(NoUnwind,1<<5) ///< Function doesn't unwind stack | |
65 | DECLARE_LLVM_ATTRIBUTE(NoAlias,1<<6) ///< Considered to not alias after call | |
66 | DECLARE_LLVM_ATTRIBUTE(ByVal,1<<7) ///< Pass structure by value | |
67 | DECLARE_LLVM_ATTRIBUTE(Nest,1<<8) ///< Nested function static chain | |
68 | DECLARE_LLVM_ATTRIBUTE(ReadNone,1<<9) ///< Function does not access memory | |
69 | DECLARE_LLVM_ATTRIBUTE(ReadOnly,1<<10) ///< Function only reads from memory | |
70 | DECLARE_LLVM_ATTRIBUTE(NoInline,1<<11) ///< inline=never | |
71 | DECLARE_LLVM_ATTRIBUTE(AlwaysInline,1<<12) ///< inline=always | |
72 | DECLARE_LLVM_ATTRIBUTE(OptimizeForSize,1<<13) ///< opt_size | |
73 | DECLARE_LLVM_ATTRIBUTE(StackProtect,1<<14) ///< Stack protection. | |
74 | DECLARE_LLVM_ATTRIBUTE(StackProtectReq,1<<15) ///< Stack protection required. | |
75 | DECLARE_LLVM_ATTRIBUTE(Alignment,31<<16) ///< Alignment of parameter (5 bits) | |
76 | // stored as log2 of alignment with +1 bias | |
77 | // 0 means unaligned different from align 1 | |
78 | DECLARE_LLVM_ATTRIBUTE(NoCapture,1<<21) ///< Function creates no aliases of pointer | |
79 | DECLARE_LLVM_ATTRIBUTE(NoRedZone,1<<22) /// disable redzone | |
80 | DECLARE_LLVM_ATTRIBUTE(NoImplicitFloat,1<<23) /// disable implicit floating point | |
81 | /// instructions. | |
82 | DECLARE_LLVM_ATTRIBUTE(Naked,1<<24) ///< Naked function | |
83 | DECLARE_LLVM_ATTRIBUTE(InlineHint,1<<25) ///< source said inlining was | |
84 | ///desirable | |
85 | DECLARE_LLVM_ATTRIBUTE(StackAlignment,7<<26) ///< Alignment of stack for | |
86 | ///function (3 bits) stored as log2 | |
87 | ///of alignment with +1 bias | |
88 | ///0 means unaligned (different from | |
89 | ///alignstack= {1)) | |
90 | DECLARE_LLVM_ATTRIBUTE(ReturnsTwice,1<<29) ///< Function can return twice | |
91 | DECLARE_LLVM_ATTRIBUTE(UWTable,1<<30) ///< Function must be in a unwind | |
92 | ///table | |
93 | DECLARE_LLVM_ATTRIBUTE(NonLazyBind,1U<<31) ///< Function is called early and/or | |
94 | /// often, so lazy binding isn't | |
95 | /// worthwhile. | |
96 | DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is on. | |
97 | ||
98 | #undef DECLARE_LLVM_ATTRIBUTE | |
99 | ||
100 | /// Note that uwtable is about the ABI or the user mandating an entry in the | |
101 | /// unwind table. The nounwind attribute is about an exception passing by the | |
102 | /// function. | |
103 | /// In a theoretical system that uses tables for profiling and sjlj for | |
104 | /// exceptions, they would be fully independent. In a normal system that | |
105 | /// uses tables for both, the semantics are: | |
106 | /// nil = Needs an entry because an exception might pass by. | |
107 | /// nounwind = No need for an entry | |
108 | /// uwtable = Needs an entry because the ABI says so and because | |
109 | /// an exception might pass by. | |
110 | /// uwtable + nounwind = Needs an entry because the ABI says so. | |
111 | ||
112 | /// @brief Attributes that only apply to function parameters. | |
113 | const AttrConst ParameterOnly = {ByVal_i | Nest_i | | |
114 | StructRet_i | NoCapture_i}; | |
115 | ||
116 | /// @brief Attributes that may be applied to the function itself. These cannot | |
117 | /// be used on return values or function parameters. | |
118 | const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i | | |
119 | ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i | | |
120 | StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i | | |
121 | Naked_i | InlineHint_i | StackAlignment_i | | |
122 | UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i}; | |
123 | ||
124 | /// @brief Parameter attributes that do not apply to vararg call arguments. | |
125 | const AttrConst VarArgsIncompatible = {StructRet_i}; | |
126 | ||
127 | /// @brief Attributes that are mutually incompatible. | |
128 | const AttrConst MutuallyIncompatible[5] = { | |
129 | {ByVal_i | Nest_i | StructRet_i}, | |
130 | {ByVal_i | Nest_i | InReg_i }, | |
131 | {ZExt_i | SExt_i}, | |
132 | {ReadNone_i | ReadOnly_i}, | |
133 | {NoInline_i | AlwaysInline_i} | |
134 | }; | |
135 | ||
136 | } // namespace Attribute | |
137 | ||
138 | /// AttributeImpl - The internal representation of the Attributes class. This is | |
139 | /// uniquified. | |
140 | class AttributesImpl; | |
141 | ||
142 | /// Attributes - A bitset of attributes. | |
143 | class Attributes { | |
144 | // Currently, we need less than 64 bits. | |
145 | uint64_t Bits; | |
146 | ||
147 | explicit Attributes(AttributesImpl *A); | |
148 | public: | |
149 | Attributes() : Bits(0) {} | |
150 | explicit Attributes(uint64_t Val) : Bits(Val) {} | |
151 | /*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) {} | |
152 | ||
153 | class Builder { | |
154 | friend class Attributes; | |
155 | uint64_t Bits; | |
156 | public: | |
157 | Builder() : Bits(0) {} | |
158 | Builder(const Attributes &A) : Bits(A.Bits) {} | |
159 | ||
160 | void addZExtAttr() { | |
161 | Bits |= Attribute::ZExt_i; | |
162 | } | |
163 | void addSExtAttr() { | |
164 | Bits |= Attribute::SExt_i; | |
165 | } | |
166 | void addNoReturnAttr() { | |
167 | Bits |= Attribute::NoReturn_i; | |
168 | } | |
169 | void addInRegAttr() { | |
170 | Bits |= Attribute::InReg_i; | |
171 | } | |
172 | void addStructRetAttr() { | |
173 | Bits |= Attribute::StructRet_i; | |
174 | } | |
175 | void addNoUnwindAttr() { | |
176 | Bits |= Attribute::NoUnwind_i; | |
177 | } | |
178 | void addNoAliasAttr() { | |
179 | Bits |= Attribute::NoAlias_i; | |
180 | } | |
181 | void addByValAttr() { | |
182 | Bits |= Attribute::ByVal_i; | |
183 | } | |
184 | void addNestAttr() { | |
185 | Bits |= Attribute::Nest_i; | |
186 | } | |
187 | void addReadNoneAttr() { | |
188 | Bits |= Attribute::ReadNone_i; | |
189 | } | |
190 | void addReadOnlyAttr() { | |
191 | Bits |= Attribute::ReadOnly_i; | |
192 | } | |
193 | void addNoInlineAttr() { | |
194 | Bits |= Attribute::NoInline_i; | |
195 | } | |
196 | void addAlwaysInlineAttr() { | |
197 | Bits |= Attribute::AlwaysInline_i; | |
198 | } | |
199 | void addOptimizeForSizeAttr() { | |
200 | Bits |= Attribute::OptimizeForSize_i; | |
201 | } | |
202 | void addStackProtectAttr() { | |
203 | Bits |= Attribute::StackProtect_i; | |
204 | } | |
205 | void addStackProtectReqAttr() { | |
206 | Bits |= Attribute::StackProtectReq_i; | |
207 | } | |
208 | void addNoCaptureAttr() { | |
209 | Bits |= Attribute::NoCapture_i; | |
210 | } | |
211 | void addNoRedZoneAttr() { | |
212 | Bits |= Attribute::NoRedZone_i; | |
213 | } | |
214 | void addNoImplicitFloatAttr() { | |
215 | Bits |= Attribute::NoImplicitFloat_i; | |
216 | } | |
217 | void addNakedAttr() { | |
218 | Bits |= Attribute::Naked_i; | |
219 | } | |
220 | void addInlineHintAttr() { | |
221 | Bits |= Attribute::InlineHint_i; | |
222 | } | |
223 | void addReturnsTwiceAttr() { | |
224 | Bits |= Attribute::ReturnsTwice_i; | |
225 | } | |
226 | void addUWTableAttr() { | |
227 | Bits |= Attribute::UWTable_i; | |
228 | } | |
229 | void addNonLazyBindAttr() { | |
230 | Bits |= Attribute::NonLazyBind_i; | |
231 | } | |
232 | void addAddressSafetyAttr() { | |
233 | Bits |= Attribute::AddressSafety_i; | |
234 | } | |
235 | void addAlignmentAttr(unsigned Align) { | |
236 | if (Align == 0) return; | |
237 | assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); | |
238 | assert(Align <= 0x40000000 && "Alignment too large."); | |
239 | Bits |= (Log2_32(Align) + 1) << 16; | |
240 | } | |
241 | void addStackAlignmentAttr(unsigned Align) { | |
242 | // Default alignment, allow the target to define how to align it. | |
243 | if (Align == 0) return; | |
244 | ||
245 | assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); | |
246 | assert(Align <= 0x100 && "Alignment too large."); | |
247 | Bits |= (Log2_32(Align) + 1) << 26; | |
248 | } | |
249 | }; | |
250 | ||
251 | /// get - Return a uniquified Attributes object. This takes the uniquified | |
252 | /// value from the Builder and wraps it in the Attributes class. | |
253 | static Attributes get(LLVMContext &Context, Builder &B); | |
254 | ||
255 | // Attribute query methods. | |
256 | // FIXME: StackAlignment & Alignment attributes have no predicate methods. | |
257 | bool hasAttributes() const { | |
258 | return Bits != 0; | |
259 | } | |
260 | bool hasAttributes(const Attributes &A) const { | |
261 | return Bits & A.Bits; | |
262 | } | |
263 | ||
264 | bool hasZExtAttr() const { | |
265 | return Bits & Attribute::ZExt_i; | |
266 | } | |
267 | bool hasSExtAttr() const { | |
268 | return Bits & Attribute::SExt_i; | |
269 | } | |
270 | bool hasNoReturnAttr() const { | |
271 | return Bits & Attribute::NoReturn_i; | |
272 | } | |
273 | bool hasInRegAttr() const { | |
274 | return Bits & Attribute::InReg_i; | |
275 | } | |
276 | bool hasStructRetAttr() const { | |
277 | return Bits & Attribute::StructRet_i; | |
278 | } | |
279 | bool hasNoUnwindAttr() const { | |
280 | return Bits & Attribute::NoUnwind_i; | |
281 | } | |
282 | bool hasNoAliasAttr() const { | |
283 | return Bits & Attribute::NoAlias_i; | |
284 | } | |
285 | bool hasByValAttr() const { | |
286 | return Bits & Attribute::ByVal_i; | |
287 | } | |
288 | bool hasNestAttr() const { | |
289 | return Bits & Attribute::Nest_i; | |
290 | } | |
291 | bool hasReadNoneAttr() const { | |
292 | return Bits & Attribute::ReadNone_i; | |
293 | } | |
294 | bool hasReadOnlyAttr() const { | |
295 | return Bits & Attribute::ReadOnly_i; | |
296 | } | |
297 | bool hasNoInlineAttr() const { | |
298 | return Bits & Attribute::NoInline_i; | |
299 | } | |
300 | bool hasAlwaysInlineAttr() const { | |
301 | return Bits & Attribute::AlwaysInline_i; | |
302 | } | |
303 | bool hasOptimizeForSizeAttr() const { | |
304 | return Bits & Attribute::OptimizeForSize_i; | |
305 | } | |
306 | bool hasStackProtectAttr() const { | |
307 | return Bits & Attribute::StackProtect_i; | |
308 | } | |
309 | bool hasStackProtectReqAttr() const { | |
310 | return Bits & Attribute::StackProtectReq_i; | |
311 | } | |
312 | bool hasAlignmentAttr() const { | |
313 | return Bits & Attribute::Alignment_i; | |
314 | } | |
315 | bool hasNoCaptureAttr() const { | |
316 | return Bits & Attribute::NoCapture_i; | |
317 | } | |
318 | bool hasNoRedZoneAttr() const { | |
319 | return Bits & Attribute::NoRedZone_i; | |
320 | } | |
321 | bool hasNoImplicitFloatAttr() const { | |
322 | return Bits & Attribute::NoImplicitFloat_i; | |
323 | } | |
324 | bool hasNakedAttr() const { | |
325 | return Bits & Attribute::Naked_i; | |
326 | } | |
327 | bool hasInlineHintAttr() const { | |
328 | return Bits & Attribute::InlineHint_i; | |
329 | } | |
330 | bool hasReturnsTwiceAttr() const { | |
331 | return Bits & Attribute::ReturnsTwice_i; | |
332 | } | |
333 | bool hasStackAlignmentAttr() const { | |
334 | return Bits & Attribute::StackAlignment_i; | |
335 | } | |
336 | bool hasUWTableAttr() const { | |
337 | return Bits & Attribute::UWTable_i; | |
338 | } | |
339 | bool hasNonLazyBindAttr() const { | |
340 | return Bits & Attribute::NonLazyBind_i; | |
341 | } | |
342 | bool hasAddressSafetyAttr() const { | |
343 | return Bits & Attribute::AddressSafety_i; | |
344 | } | |
345 | ||
346 | /// This returns the alignment field of an attribute as a byte alignment | |
347 | /// value. | |
348 | unsigned getAlignment() const { | |
349 | if (!hasAlignmentAttr()) | |
350 | return 0; | |
351 | return 1U << (((Bits & Attribute::Alignment_i) >> 16) - 1); | |
352 | } | |
353 | ||
354 | /// This returns the stack alignment field of an attribute as a byte alignment | |
355 | /// value. | |
356 | unsigned getStackAlignment() const { | |
357 | if (!hasStackAlignmentAttr()) | |
358 | return 0; | |
359 | return 1U << (((Bits & Attribute::StackAlignment_i) >> 26) - 1); | |
360 | } | |
361 | ||
362 | // This is a "safe bool() operator". | |
363 | operator const void *() const { return Bits ? this : 0; } | |
364 | bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; } | |
365 | bool operator == (const Attributes &Attrs) const { | |
366 | return Bits == Attrs.Bits; | |
367 | } | |
368 | bool operator != (const Attributes &Attrs) const { | |
369 | return Bits != Attrs.Bits; | |
370 | } | |
371 | Attributes operator | (const Attributes &Attrs) const { | |
372 | return Attributes(Bits | Attrs.Bits); | |
373 | } | |
374 | Attributes operator & (const Attributes &Attrs) const { | |
375 | return Attributes(Bits & Attrs.Bits); | |
376 | } | |
377 | Attributes operator ^ (const Attributes &Attrs) const { | |
378 | return Attributes(Bits ^ Attrs.Bits); | |
379 | } | |
380 | Attributes &operator |= (const Attributes &Attrs) { | |
381 | Bits |= Attrs.Bits; | |
382 | return *this; | |
383 | } | |
384 | Attributes &operator &= (const Attributes &Attrs) { | |
385 | Bits &= Attrs.Bits; | |
386 | return *this; | |
387 | } | |
388 | Attributes operator ~ () const { return Attributes(~Bits); } | |
389 | uint64_t Raw() const { return Bits; } | |
390 | ||
391 | /// This turns an int alignment (a power of 2, normally) into the form used | |
392 | /// internally in Attributes. | |
393 | static Attributes constructAlignmentFromInt(unsigned i) { | |
394 | // Default alignment, allow the target to define how to align it. | |
395 | if (i == 0) | |
396 | return Attribute::None; | |
397 | ||
398 | assert(isPowerOf2_32(i) && "Alignment must be a power of two."); | |
399 | assert(i <= 0x40000000 && "Alignment too large."); | |
400 | return Attributes((Log2_32(i)+1) << 16); | |
401 | } | |
402 | ||
403 | /// This turns an int stack alignment (which must be a power of 2) into the | |
404 | /// form used internally in Attributes. | |
405 | static Attributes constructStackAlignmentFromInt(unsigned i) { | |
406 | // Default alignment, allow the target to define how to align it. | |
407 | if (i == 0) | |
408 | return Attribute::None; | |
409 | ||
410 | assert(isPowerOf2_32(i) && "Alignment must be a power of two."); | |
411 | assert(i <= 0x100 && "Alignment too large."); | |
412 | return Attributes((Log2_32(i)+1) << 26); | |
413 | } | |
414 | ||
415 | /// @brief Which attributes cannot be applied to a type. | |
416 | static Attributes typeIncompatible(Type *Ty); | |
417 | ||
418 | /// This returns an integer containing an encoding of all the LLVM attributes | |
419 | /// found in the given attribute bitset. Any change to this encoding is a | |
420 | /// breaking change to bitcode compatibility. | |
421 | static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) { | |
422 | // FIXME: It doesn't make sense to store the alignment information as an | |
423 | // expanded out value, we should store it as a log2 value. However, we | |
424 | // can't just change that here without breaking bitcode compatibility. If | |
425 | // this ever becomes a problem in practice, we should introduce new tag | |
426 | // numbers in the bitcode file and have those tags use a more efficiently | |
427 | // encoded alignment field. | |
428 | ||
429 | // Store the alignment in the bitcode as a 16-bit raw value instead of a | |
430 | // 5-bit log2 encoded value. Shift the bits above the alignment up by 11 | |
431 | // bits. | |
432 | uint64_t EncodedAttrs = Attrs.Raw() & 0xffff; | |
433 | if (Attrs.hasAlignmentAttr()) | |
434 | EncodedAttrs |= (1ULL << 16) << | |
435 | (((Attrs.Bits & Attribute::Alignment_i) - 1) >> 16); | |
436 | EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11; | |
437 | return EncodedAttrs; | |
438 | } | |
439 | ||
440 | /// This returns an attribute bitset containing the LLVM attributes that have | |
441 | /// been decoded from the given integer. This function must stay in sync with | |
442 | /// 'encodeLLVMAttributesForBitcode'. | |
443 | static Attributes decodeLLVMAttributesForBitcode(uint64_t EncodedAttrs) { | |
444 | // The alignment is stored as a 16-bit raw value from bits 31--16. We shift | |
445 | // the bits above 31 down by 11 bits. | |
446 | unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; | |
447 | assert((!Alignment || isPowerOf2_32(Alignment)) && | |
448 | "Alignment must be a power of two."); | |
449 | ||
450 | Attributes Attrs(EncodedAttrs & 0xffff); | |
451 | if (Alignment) | |
452 | Attrs |= Attributes::constructAlignmentFromInt(Alignment); | |
453 | Attrs |= Attributes((EncodedAttrs & (0xfffULL << 32)) >> 11); | |
454 | return Attrs; | |
455 | } | |
456 | ||
457 | /// The set of Attributes set in Attributes is converted to a string of | |
458 | /// equivalent mnemonics. This is, presumably, for writing out the mnemonics | |
459 | /// for the assembly writer. | |
460 | /// @brief Convert attribute bits to text | |
461 | std::string getAsString() const; | |
462 | }; | |
463 | ||
464 | /// This is just a pair of values to associate a set of attributes | |
465 | /// with an index. | |
466 | struct AttributeWithIndex { | |
467 | Attributes Attrs; ///< The attributes that are set, or'd together. | |
468 | unsigned Index; ///< Index of the parameter for which the attributes apply. | |
469 | ///< Index 0 is used for return value attributes. | |
470 | ///< Index ~0U is used for function attributes. | |
471 | ||
472 | static AttributeWithIndex get(unsigned Idx, Attributes Attrs) { | |
473 | AttributeWithIndex P; | |
474 | P.Index = Idx; | |
475 | P.Attrs = Attrs; | |
476 | return P; | |
477 | } | |
478 | }; | |
479 | ||
480 | //===----------------------------------------------------------------------===// | |
481 | // AttrListPtr Smart Pointer | |
482 | //===----------------------------------------------------------------------===// | |
483 | ||
484 | class AttributeListImpl; | |
485 | ||
486 | /// AttrListPtr - This class manages the ref count for the opaque | |
487 | /// AttributeListImpl object and provides accessors for it. | |
488 | class AttrListPtr { | |
489 | /// AttrList - The attributes that we are managing. This can be null | |
490 | /// to represent the empty attributes list. | |
491 | AttributeListImpl *AttrList; | |
492 | public: | |
493 | AttrListPtr() : AttrList(0) {} | |
494 | AttrListPtr(const AttrListPtr &P); | |
495 | const AttrListPtr &operator=(const AttrListPtr &RHS); | |
496 | ~AttrListPtr(); | |
497 | ||
498 | //===--------------------------------------------------------------------===// | |
499 | // Attribute List Construction and Mutation | |
500 | //===--------------------------------------------------------------------===// | |
501 | ||
502 | /// get - Return a Attributes list with the specified parameters in it. | |
503 | static AttrListPtr get(ArrayRef<AttributeWithIndex> Attrs); | |
504 | ||
505 | /// addAttr - Add the specified attribute at the specified index to this | |
506 | /// attribute list. Since attribute lists are immutable, this | |
507 | /// returns the new list. | |
508 | AttrListPtr addAttr(unsigned Idx, Attributes Attrs) const; | |
509 | ||
510 | /// removeAttr - Remove the specified attribute at the specified index from | |
511 | /// this attribute list. Since attribute lists are immutable, this | |
512 | /// returns the new list. | |
513 | AttrListPtr removeAttr(unsigned Idx, Attributes Attrs) const; | |
514 | ||
515 | //===--------------------------------------------------------------------===// | |
516 | // Attribute List Accessors | |
517 | //===--------------------------------------------------------------------===// | |
518 | /// getParamAttributes - The attributes for the specified index are | |
519 | /// returned. | |
520 | Attributes getParamAttributes(unsigned Idx) const { | |
521 | assert (Idx && Idx != ~0U && "Invalid parameter index!"); | |
522 | return getAttributes(Idx); | |
523 | } | |
524 | ||
525 | /// getRetAttributes - The attributes for the ret value are | |
526 | /// returned. | |
527 | Attributes getRetAttributes() const { | |
528 | return getAttributes(0); | |
529 | } | |
530 | ||
531 | /// getFnAttributes - The function attributes are returned. | |
532 | Attributes getFnAttributes() const { | |
533 | return getAttributes(~0U); | |
534 | } | |
535 | ||
536 | /// paramHasAttr - Return true if the specified parameter index has the | |
537 | /// specified attribute set. | |
538 | bool paramHasAttr(unsigned Idx, Attributes Attr) const { | |
539 | return getAttributes(Idx).hasAttributes(Attr); | |
540 | } | |
541 | ||
542 | /// getParamAlignment - Return the alignment for the specified function | |
543 | /// parameter. | |
544 | unsigned getParamAlignment(unsigned Idx) const { | |
545 | return getAttributes(Idx).getAlignment(); | |
546 | } | |
547 | ||
548 | /// hasAttrSomewhere - Return true if the specified attribute is set for at | |
549 | /// least one parameter or for the return value. | |
550 | bool hasAttrSomewhere(Attributes Attr) const; | |
551 | ||
552 | /// operator==/!= - Provide equality predicates. | |
553 | bool operator==(const AttrListPtr &RHS) const | |
554 | { return AttrList == RHS.AttrList; } | |
555 | bool operator!=(const AttrListPtr &RHS) const | |
556 | { return AttrList != RHS.AttrList; } | |
557 | ||
558 | void dump() const; | |
559 | ||
560 | //===--------------------------------------------------------------------===// | |
561 | // Attribute List Introspection | |
562 | //===--------------------------------------------------------------------===// | |
563 | ||
564 | /// getRawPointer - Return a raw pointer that uniquely identifies this | |
565 | /// attribute list. | |
566 | void *getRawPointer() const { | |
567 | return AttrList; | |
568 | } | |
569 | ||
570 | // Attributes are stored as a dense set of slots, where there is one | |
571 | // slot for each argument that has an attribute. This allows walking over the | |
572 | // dense set instead of walking the sparse list of attributes. | |
573 | ||
574 | /// isEmpty - Return true if there are no attributes. | |
575 | /// | |
576 | bool isEmpty() const { | |
577 | return AttrList == 0; | |
578 | } | |
579 | ||
580 | /// getNumSlots - Return the number of slots used in this attribute list. | |
581 | /// This is the number of arguments that have an attribute set on them | |
582 | /// (including the function itself). | |
583 | unsigned getNumSlots() const; | |
584 | ||
585 | /// getSlot - Return the AttributeWithIndex at the specified slot. This | |
586 | /// holds a index number plus a set of attributes. | |
587 | const AttributeWithIndex &getSlot(unsigned Slot) const; | |
588 | ||
589 | private: | |
590 | explicit AttrListPtr(AttributeListImpl *L); | |
591 | ||
592 | /// getAttributes - The attributes for the specified index are | |
593 | /// returned. Attributes for the result are denoted with Idx = 0. | |
594 | Attributes getAttributes(unsigned Idx) const; | |
595 | ||
596 | }; | |
597 | ||
598 | } // End llvm namespace | |
599 | ||
600 | #endif |