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