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