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