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