blob: 03ab0f07020b3bd932e3c1710b0ce5325d61be81 [file] [log] [blame]
Shih-wei Liaof8fd82b2010-02-10 11:10:31 -08001//===--- Attr.h - Classes for representing expressions ----------*- 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 defines the Attr interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_ATTR_H
15#define LLVM_CLANG_AST_ATTR_H
16
17#include "llvm/Support/Casting.h"
18#include "llvm/ADT/StringRef.h"
19#include <cassert>
20#include <cstring>
21#include <string>
22#include <algorithm>
23using llvm::dyn_cast;
24
25namespace clang {
26 class ASTContext;
27}
28
29
30// Defined in ASTContext.h
31void *operator new(size_t Bytes, clang::ASTContext &C,
32 size_t Alignment = 16) throw ();
33
34// It is good practice to pair new/delete operators. Also, MSVC gives many
35// warnings if a matching delete overload is not declared, even though the
36// throw() spec guarantees it will not be implicitly called.
37void operator delete(void *Ptr, clang::ASTContext &C, size_t)
38 throw ();
39
40namespace clang {
41
42/// Attr - This represents one attribute.
43class Attr {
44public:
45 enum Kind {
46 Alias,
47 Aligned,
48 AlwaysInline,
49 AnalyzerNoReturn, // Clang-specific.
50 Annotate,
51 AsmLabel, // Represent GCC asm label extension.
52 BaseCheck,
53 Blocks,
54 CDecl,
55 Cleanup,
56 Const,
57 Constructor,
58 Deprecated,
59 Destructor,
60 FastCall,
61 Final,
62 Format,
63 FormatArg,
64 GNUInline,
65 Hiding,
66 IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
67 Malloc,
68 NoDebug,
69 NoInline,
70 NonNull,
71 NoReturn,
72 NoThrow,
73 ObjCException,
74 ObjCNSObject,
75 Override,
76 CFReturnsRetained, // Clang/Checker-specific.
77 NSReturnsRetained, // Clang/Checker-specific.
78 Overloadable, // Clang-specific
79 Packed,
80 PragmaPack,
81 Pure,
82 Regparm,
83 ReqdWorkGroupSize, // OpenCL-specific
84 Section,
85 Sentinel,
86 StdCall,
87 TransparentUnion,
88 Unavailable,
89 Unused,
90 Used,
91 Visibility,
92 WarnUnusedResult,
93 Weak,
94 WeakImport,
95
96 FIRST_TARGET_ATTRIBUTE,
97 DLLExport,
98 DLLImport,
99 MSP430Interrupt
100 };
101
102private:
103 Attr *Next;
104 Kind AttrKind;
105 bool Inherited : 1;
106
107protected:
108 void* operator new(size_t bytes) throw() {
109 assert(0 && "Attrs cannot be allocated with regular 'new'.");
110 return 0;
111 }
112 void operator delete(void* data) throw() {
113 assert(0 && "Attrs cannot be released with regular 'delete'.");
114 }
115
116protected:
117 Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
118 virtual ~Attr() {
119 assert(Next == 0 && "Destroy didn't work");
120 }
121public:
122
123 void Destroy(ASTContext &C);
124
125 /// \brief Whether this attribute should be merged to new
126 /// declarations.
127 virtual bool isMerged() const { return true; }
128
129 Kind getKind() const { return AttrKind; }
130
131 Attr *getNext() { return Next; }
132 const Attr *getNext() const { return Next; }
133 void setNext(Attr *next) { Next = next; }
134
135 template<typename T> const T *getNext() const {
136 for (const Attr *attr = getNext(); attr; attr = attr->getNext())
137 if (const T *V = dyn_cast<T>(attr))
138 return V;
139 return 0;
140 }
141
142 bool isInherited() const { return Inherited; }
143 void setInherited(bool value) { Inherited = value; }
144
145 void addAttr(Attr *attr) {
146 assert((attr != 0) && "addAttr(): attr is null");
147
148 // FIXME: This doesn't preserve the order in any way.
149 attr->Next = Next;
150 Next = attr;
151 }
152
153 // Clone this attribute.
154 virtual Attr* clone(ASTContext &C) const = 0;
155
156 // Implement isa/cast/dyncast/etc.
157 static bool classof(const Attr *) { return true; }
158};
159
160#define DEF_SIMPLE_ATTR(ATTR) \
161class ATTR##Attr : public Attr { \
162public: \
163 ATTR##Attr() : Attr(ATTR) {} \
164 virtual Attr *clone(ASTContext &C) const; \
165 static bool classof(const Attr *A) { return A->getKind() == ATTR; } \
166 static bool classof(const ATTR##Attr *A) { return true; } \
167}
168
169DEF_SIMPLE_ATTR(Packed);
170
171class PragmaPackAttr : public Attr {
172 unsigned Alignment;
173
174public:
175 PragmaPackAttr(unsigned alignment) : Attr(PragmaPack), Alignment(alignment) {}
176
177 /// getAlignment - The specified alignment in bits.
178 unsigned getAlignment() const { return Alignment; }
179
180 virtual Attr* clone(ASTContext &C) const;
181
182 // Implement isa/cast/dyncast/etc.
183 static bool classof(const Attr *A) {
184 return A->getKind() == PragmaPack;
185 }
186 static bool classof(const PragmaPackAttr *A) { return true; }
187};
188
189class AlignedAttr : public Attr {
190 unsigned Alignment;
191public:
192 AlignedAttr(unsigned alignment)
193 : Attr(Aligned), Alignment(alignment) {}
194
195 /// getAlignment - The specified alignment in bits.
196 unsigned getAlignment() const { return Alignment; }
197
198 /// getMaxAlignment - Get the maximum alignment of attributes on this list.
199 unsigned getMaxAlignment() const {
200 const AlignedAttr *Next = getNext<AlignedAttr>();
201 if (Next)
202 return std::max(Next->getMaxAlignment(), Alignment);
203 else
204 return Alignment;
205 }
206
207 virtual Attr* clone(ASTContext &C) const;
208
209 // Implement isa/cast/dyncast/etc.
210 static bool classof(const Attr *A) {
211 return A->getKind() == Aligned;
212 }
213 static bool classof(const AlignedAttr *A) { return true; }
214};
215
216class AnnotateAttr : public Attr {
217 std::string Annotation;
218public:
219 AnnotateAttr(llvm::StringRef ann) : Attr(Annotate), Annotation(ann) {}
220
221 const std::string& getAnnotation() const { return Annotation; }
222
223 virtual Attr* clone(ASTContext &C) const;
224
225 // Implement isa/cast/dyncast/etc.
226 static bool classof(const Attr *A) {
227 return A->getKind() == Annotate;
228 }
229 static bool classof(const AnnotateAttr *A) { return true; }
230};
231
232class AsmLabelAttr : public Attr {
233 std::string Label;
234public:
235 AsmLabelAttr(llvm::StringRef L) : Attr(AsmLabel), Label(L) {}
236
237 const std::string& getLabel() const { return Label; }
238
239 virtual Attr* clone(ASTContext &C) const;
240
241 // Implement isa/cast/dyncast/etc.
242 static bool classof(const Attr *A) {
243 return A->getKind() == AsmLabel;
244 }
245 static bool classof(const AsmLabelAttr *A) { return true; }
246};
247
248DEF_SIMPLE_ATTR(AlwaysInline);
249
250class AliasAttr : public Attr {
251 std::string Aliasee;
252public:
253 AliasAttr(llvm::StringRef aliasee) : Attr(Alias), Aliasee(aliasee) {}
254
255 const std::string& getAliasee() const { return Aliasee; }
256
257 virtual Attr *clone(ASTContext &C) const;
258
259 // Implement isa/cast/dyncast/etc.
260 static bool classof(const Attr *A) { return A->getKind() == Alias; }
261 static bool classof(const AliasAttr *A) { return true; }
262};
263
264class ConstructorAttr : public Attr {
265 int priority;
266public:
267 ConstructorAttr(int p) : Attr(Constructor), priority(p) {}
268
269 int getPriority() const { return priority; }
270
271 virtual Attr *clone(ASTContext &C) const;
272
273 // Implement isa/cast/dyncast/etc.
274 static bool classof(const Attr *A) { return A->getKind() == Constructor; }
275 static bool classof(const ConstructorAttr *A) { return true; }
276};
277
278class DestructorAttr : public Attr {
279 int priority;
280public:
281 DestructorAttr(int p) : Attr(Destructor), priority(p) {}
282
283 int getPriority() const { return priority; }
284
285 virtual Attr *clone(ASTContext &C) const;
286
287 // Implement isa/cast/dyncast/etc.
288 static bool classof(const Attr *A) { return A->getKind() == Destructor; }
289 static bool classof(const DestructorAttr *A) { return true; }
290};
291
292class GNUInlineAttr : public Attr {
293public:
294 GNUInlineAttr() : Attr(GNUInline) {}
295
296 virtual Attr *clone(ASTContext &C) const;
297
298 // Implement isa/cast/dyncast/etc.
299 static bool classof(const Attr *A) {
300 return A->getKind() == GNUInline;
301 }
302 static bool classof(const GNUInlineAttr *A) { return true; }
303};
304
305class IBOutletAttr : public Attr {
306public:
307 IBOutletAttr() : Attr(IBOutletKind) {}
308
309 virtual Attr *clone(ASTContext &C) const;
310
311 // Implement isa/cast/dyncast/etc.
312 static bool classof(const Attr *A) {
313 return A->getKind() == IBOutletKind;
314 }
315 static bool classof(const IBOutletAttr *A) { return true; }
316};
317
318DEF_SIMPLE_ATTR(Malloc);
319DEF_SIMPLE_ATTR(NoReturn);
320DEF_SIMPLE_ATTR(AnalyzerNoReturn);
321DEF_SIMPLE_ATTR(Deprecated);
322DEF_SIMPLE_ATTR(Final);
323
324class SectionAttr : public Attr {
325 std::string Name;
326public:
327 SectionAttr(llvm::StringRef N) : Attr(Section), Name(N) {}
328
329 const std::string& getName() const { return Name; }
330
331 virtual Attr *clone(ASTContext &C) const;
332
333 // Implement isa/cast/dyncast/etc.
334 static bool classof(const Attr *A) {
335 return A->getKind() == Section;
336 }
337 static bool classof(const SectionAttr *A) { return true; }
338};
339
340DEF_SIMPLE_ATTR(Unavailable);
341DEF_SIMPLE_ATTR(Unused);
342DEF_SIMPLE_ATTR(Used);
343DEF_SIMPLE_ATTR(Weak);
344DEF_SIMPLE_ATTR(WeakImport);
345DEF_SIMPLE_ATTR(NoThrow);
346DEF_SIMPLE_ATTR(Const);
347DEF_SIMPLE_ATTR(Pure);
348
349class NonNullAttr : public Attr {
350 unsigned* ArgNums;
351 unsigned Size;
352public:
353 NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
354 ArgNums(0), Size(0) {
355
356 if (size == 0) return;
357 assert(arg_nums);
358 ArgNums = new unsigned[size];
359 Size = size;
360 memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
361 }
362
363 virtual ~NonNullAttr() {
364 delete [] ArgNums;
365 }
366
367 typedef const unsigned *iterator;
368 iterator begin() const { return ArgNums; }
369 iterator end() const { return ArgNums + Size; }
370 unsigned size() const { return Size; }
371
372 bool isNonNull(unsigned arg) const {
373 return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
374 }
375
376 virtual Attr *clone(ASTContext &C) const;
377
378 static bool classof(const Attr *A) { return A->getKind() == NonNull; }
379 static bool classof(const NonNullAttr *A) { return true; }
380};
381
382class FormatAttr : public Attr {
383 std::string Type;
384 int formatIdx, firstArg;
385public:
386 FormatAttr(llvm::StringRef type, int idx, int first) : Attr(Format),
387 Type(type), formatIdx(idx), firstArg(first) {}
388
389 const std::string& getType() const { return Type; }
390 void setType(llvm::StringRef type) { Type = type; }
391 int getFormatIdx() const { return formatIdx; }
392 int getFirstArg() const { return firstArg; }
393
394 virtual Attr *clone(ASTContext &C) const;
395
396 // Implement isa/cast/dyncast/etc.
397 static bool classof(const Attr *A) { return A->getKind() == Format; }
398 static bool classof(const FormatAttr *A) { return true; }
399};
400
401class FormatArgAttr : public Attr {
402 int formatIdx;
403public:
404 FormatArgAttr(int idx) : Attr(FormatArg), formatIdx(idx) {}
405 int getFormatIdx() const { return formatIdx; }
406
407 virtual Attr *clone(ASTContext &C) const;
408
409 // Implement isa/cast/dyncast/etc.
410 static bool classof(const Attr *A) { return A->getKind() == FormatArg; }
411 static bool classof(const FormatArgAttr *A) { return true; }
412};
413
414class SentinelAttr : public Attr {
415 int sentinel, NullPos;
416public:
417 SentinelAttr(int sentinel_val, int nullPos) : Attr(Sentinel),
418 sentinel(sentinel_val), NullPos(nullPos) {}
419 int getSentinel() const { return sentinel; }
420 int getNullPos() const { return NullPos; }
421
422 virtual Attr *clone(ASTContext &C) const;
423
424 // Implement isa/cast/dyncast/etc.
425 static bool classof(const Attr *A) { return A->getKind() == Sentinel; }
426 static bool classof(const SentinelAttr *A) { return true; }
427};
428
429class VisibilityAttr : public Attr {
430public:
431 /// @brief An enumeration for the kinds of visibility of symbols.
432 enum VisibilityTypes {
433 DefaultVisibility = 0,
434 HiddenVisibility,
435 ProtectedVisibility
436 };
437private:
438 VisibilityTypes VisibilityType;
439public:
440 VisibilityAttr(VisibilityTypes v) : Attr(Visibility),
441 VisibilityType(v) {}
442
443 VisibilityTypes getVisibility() const { return VisibilityType; }
444
445 virtual Attr *clone(ASTContext &C) const;
446
447 // Implement isa/cast/dyncast/etc.
448 static bool classof(const Attr *A) { return A->getKind() == Visibility; }
449 static bool classof(const VisibilityAttr *A) { return true; }
450};
451
452DEF_SIMPLE_ATTR(FastCall);
453DEF_SIMPLE_ATTR(StdCall);
454DEF_SIMPLE_ATTR(CDecl);
455DEF_SIMPLE_ATTR(TransparentUnion);
456DEF_SIMPLE_ATTR(ObjCNSObject);
457DEF_SIMPLE_ATTR(ObjCException);
458
459class OverloadableAttr : public Attr {
460public:
461 OverloadableAttr() : Attr(Overloadable) { }
462
463 virtual bool isMerged() const { return false; }
464
465 virtual Attr *clone(ASTContext &C) const;
466
467 static bool classof(const Attr *A) { return A->getKind() == Overloadable; }
468 static bool classof(const OverloadableAttr *) { return true; }
469};
470
471class BlocksAttr : public Attr {
472public:
473 enum BlocksAttrTypes {
474 ByRef = 0
475 };
476private:
477 BlocksAttrTypes BlocksAttrType;
478public:
479 BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {}
480
481 BlocksAttrTypes getType() const { return BlocksAttrType; }
482
483 virtual Attr *clone(ASTContext &C) const;
484
485 // Implement isa/cast/dyncast/etc.
486 static bool classof(const Attr *A) { return A->getKind() == Blocks; }
487 static bool classof(const BlocksAttr *A) { return true; }
488};
489
490class FunctionDecl;
491
492class CleanupAttr : public Attr {
493 FunctionDecl *FD;
494
495public:
496 CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {}
497
498 const FunctionDecl *getFunctionDecl() const { return FD; }
499
500 virtual Attr *clone(ASTContext &C) const;
501
502 // Implement isa/cast/dyncast/etc.
503 static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
504 static bool classof(const CleanupAttr *A) { return true; }
505};
506
507DEF_SIMPLE_ATTR(NoDebug);
508DEF_SIMPLE_ATTR(WarnUnusedResult);
509DEF_SIMPLE_ATTR(NoInline);
510
511class RegparmAttr : public Attr {
512 unsigned NumParams;
513
514public:
515 RegparmAttr(unsigned np) : Attr(Regparm), NumParams(np) {}
516
517 unsigned getNumParams() const { return NumParams; }
518
519 virtual Attr *clone(ASTContext &C) const;
520
521 // Implement isa/cast/dyncast/etc.
522 static bool classof(const Attr *A) { return A->getKind() == Regparm; }
523 static bool classof(const RegparmAttr *A) { return true; }
524};
525
526class ReqdWorkGroupSizeAttr : public Attr {
527 unsigned X, Y, Z;
528public:
529 ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
530 : Attr(ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
531
532 unsigned getXDim() const { return X; }
533 unsigned getYDim() const { return Y; }
534 unsigned getZDim() const { return Z; }
535
536 virtual Attr *clone(ASTContext &C) const;
537
538 // Implement isa/cast/dyncast/etc.
539 static bool classof(const Attr *A) {
540 return A->getKind() == ReqdWorkGroupSize;
541 }
542 static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
543};
544
545// Checker-specific attributes.
546DEF_SIMPLE_ATTR(CFReturnsRetained);
547DEF_SIMPLE_ATTR(NSReturnsRetained);
548
549// C++0x member checking attributes.
550DEF_SIMPLE_ATTR(BaseCheck);
551DEF_SIMPLE_ATTR(Hiding);
552DEF_SIMPLE_ATTR(Override);
553
554// Target-specific attributes
555DEF_SIMPLE_ATTR(DLLImport);
556DEF_SIMPLE_ATTR(DLLExport);
557
558class MSP430InterruptAttr : public Attr {
559 unsigned Number;
560
561public:
562 MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {}
563
564 unsigned getNumber() const { return Number; }
565
566 virtual Attr *clone(ASTContext &C) const;
567
568 // Implement isa/cast/dyncast/etc.
569 static bool classof(const Attr *A) { return A->getKind() == MSP430Interrupt; }
570 static bool classof(const MSP430InterruptAttr *A) { return true; }
571};
572
573#undef DEF_SIMPLE_ATTR
574
575} // end namespace clang
576
577#endif