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