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