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