Attr.h revision d99b345a1ae77c746ef025e6a050908d69e2c543
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 <cassert>
18#include <cstring>
19#include <string>
20#include <algorithm>
21
22namespace clang {
23  class ASTContext;
24}
25
26
27// Defined in ASTContext.cpp
28void *operator new(size_t Bytes, clang::ASTContext &C,
29                   size_t Alignment = 16) throw ();
30
31namespace clang {
32
33/// Attr - This represents one attribute.
34class Attr {
35public:
36  enum Kind {
37    Alias,
38    Aligned,
39    AlwaysInline,
40    AnalyzerNoReturn, // Clang-specific.
41    Annotate,
42    AsmLabel, // Represent GCC asm label extension.
43    Blocks,
44    Cleanup,
45    Const,
46    Constructor,
47    DLLExport,
48    DLLImport,
49    Deprecated,
50    Destructor,
51    FastCall,
52    Format,
53    GNUInline,
54    IBOutletKind, // Clang-specific.  Use "Kind" suffix to not conflict with
55    NoReturn,
56    NoThrow,
57    Nodebug,
58    Noinline,
59    NonNull,
60    ObjCException,
61    ObjCNSObject,
62    CFOwnershipRelease,       // Clang/Checker-specific.
63    CFOwnershipRetain,        // Clang/Checker-specific.
64    NSOwnershipRelease,         // Clang/Checker-specific.
65    NSOwnershipRetain,          // Clang/Checker-specific.
66    NSOwnershipReturns,         // Clang/Checker-specific.
67    Overloadable, // Clang-specific
68    Packed,
69    Pure,
70    Regparm,
71    Section,
72    StdCall,
73    TransparentUnion,
74    Unavailable,
75    Unused,
76    Used,
77    Visibility,
78    WarnUnusedResult,
79    Weak,
80    WeakImport
81  };
82
83private:
84  Attr *Next;
85  Kind AttrKind;
86  bool Inherited : 1;
87
88protected:
89  void* operator new(size_t bytes) throw() {
90    assert(0 && "Attrs cannot be allocated with regular 'new'.");
91    return 0;
92  }
93  void operator delete(void* data) throw() {
94    assert(0 && "Attrs cannot be released with regular 'delete'.");
95  }
96
97protected:
98  Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
99  virtual ~Attr() {
100    assert(Next == 0 && "Destroy didn't work");
101  }
102public:
103
104  void Destroy(ASTContext &C);
105
106  /// \brief Whether this attribute should be merged to new
107  /// declarations.
108  virtual bool isMerged() const { return true; }
109
110  Kind getKind() const { return AttrKind; }
111
112  Attr *getNext() { return Next; }
113  const Attr *getNext() const { return Next; }
114  void setNext(Attr *next) { Next = next; }
115
116  bool isInherited() const { return Inherited; }
117  void setInherited(bool value) { Inherited = value; }
118
119  void addAttr(Attr *attr) {
120    assert((attr != 0) && "addAttr(): attr is null");
121
122    // FIXME: This doesn't preserve the order in any way.
123    attr->Next = Next;
124    Next = attr;
125  }
126
127  // Clone this attribute.
128  virtual Attr* clone(ASTContext &C) const = 0;
129
130  // Implement isa/cast/dyncast/etc.
131  static bool classof(const Attr *) { return true; }
132};
133
134#define DEF_SIMPLE_ATTR(ATTR)                                           \
135class ATTR##Attr : public Attr {                                        \
136public:                                                                 \
137  ATTR##Attr() : Attr(ATTR) {}                                          \
138  virtual Attr *clone(ASTContext &C) const { return ::new (C) ATTR##Attr; }                \
139  static bool classof(const Attr *A) { return A->getKind() == ATTR; }   \
140  static bool classof(const ATTR##Attr *A) { return true; }             \
141}
142
143class PackedAttr : public Attr {
144  unsigned Alignment;
145
146public:
147  PackedAttr(unsigned alignment) : Attr(Packed), Alignment(alignment) {}
148
149  /// getAlignment - The specified alignment in bits.
150  unsigned getAlignment() const { return Alignment; }
151
152  virtual Attr* clone(ASTContext &C) const {
153    return ::new (C) PackedAttr(Alignment);
154  }
155
156  // Implement isa/cast/dyncast/etc.
157  static bool classof(const Attr *A) {
158    return A->getKind() == Packed;
159  }
160  static bool classof(const PackedAttr *A) { return true; }
161};
162
163class AlignedAttr : public Attr {
164  unsigned Alignment;
165public:
166  AlignedAttr(unsigned alignment) : Attr(Aligned), Alignment(alignment) {}
167
168  /// getAlignment - The specified alignment in bits.
169  unsigned getAlignment() const { return Alignment; }
170
171  virtual Attr* clone(ASTContext &C) const { return ::new (C) AlignedAttr(Alignment); }
172
173  // Implement isa/cast/dyncast/etc.
174  static bool classof(const Attr *A) {
175    return A->getKind() == Aligned;
176  }
177  static bool classof(const AlignedAttr *A) { return true; }
178};
179
180class AnnotateAttr : public Attr {
181  std::string Annotation;
182public:
183  AnnotateAttr(const std::string &ann) : Attr(Annotate), Annotation(ann) {}
184
185  const std::string& getAnnotation() const { return Annotation; }
186
187  virtual Attr* clone(ASTContext &C) const { return ::new (C) AnnotateAttr(Annotation); }
188
189  // Implement isa/cast/dyncast/etc.
190  static bool classof(const Attr *A) {
191    return A->getKind() == Annotate;
192  }
193  static bool classof(const AnnotateAttr *A) { return true; }
194};
195
196class AsmLabelAttr : public Attr {
197  std::string Label;
198public:
199  AsmLabelAttr(const std::string &L) : Attr(AsmLabel), Label(L) {}
200
201  const std::string& getLabel() const { return Label; }
202
203  virtual Attr* clone(ASTContext &C) const { return ::new (C) AsmLabelAttr(Label); }
204
205  // Implement isa/cast/dyncast/etc.
206  static bool classof(const Attr *A) {
207    return A->getKind() == AsmLabel;
208  }
209  static bool classof(const AsmLabelAttr *A) { return true; }
210};
211
212DEF_SIMPLE_ATTR(AlwaysInline);
213
214class AliasAttr : public Attr {
215  std::string Aliasee;
216public:
217  AliasAttr(const std::string &aliasee) : Attr(Alias), Aliasee(aliasee) {}
218
219  const std::string& getAliasee() const { return Aliasee; }
220
221  virtual Attr *clone(ASTContext &C) const { return ::new (C) AliasAttr(Aliasee); }
222
223  // Implement isa/cast/dyncast/etc.
224  static bool classof(const Attr *A) { return A->getKind() == Alias; }
225  static bool classof(const AliasAttr *A) { return true; }
226};
227
228class ConstructorAttr : public Attr {
229  int priority;
230public:
231  ConstructorAttr(int p) : Attr(Constructor), priority(p) {}
232
233  int getPriority() const { return priority; }
234
235  virtual Attr *clone(ASTContext &C) const { return ::new (C) ConstructorAttr(priority); }
236
237  // Implement isa/cast/dyncast/etc.
238  static bool classof(const Attr *A) { return A->getKind() == Constructor; }
239  static bool classof(const ConstructorAttr *A) { return true; }
240};
241
242class DestructorAttr : public Attr {
243  int priority;
244public:
245  DestructorAttr(int p) : Attr(Destructor), priority(p) {}
246
247  int getPriority() const { return priority; }
248
249  virtual Attr *clone(ASTContext &C) const { return ::new (C) DestructorAttr(priority); }
250
251  // Implement isa/cast/dyncast/etc.
252  static bool classof(const Attr *A) { return A->getKind() == Destructor; }
253  static bool classof(const DestructorAttr *A) { return true; }
254};
255
256class GNUInlineAttr : public Attr {
257public:
258  GNUInlineAttr() : Attr(GNUInline) {}
259
260  virtual Attr *clone(ASTContext &C) const { return ::new (C) GNUInlineAttr; }
261
262  // Implement isa/cast/dyncast/etc.
263  static bool classof(const Attr *A) {
264    return A->getKind() == GNUInline;
265  }
266  static bool classof(const GNUInlineAttr *A) { return true; }
267};
268
269class IBOutletAttr : public Attr {
270public:
271  IBOutletAttr() : Attr(IBOutletKind) {}
272
273  virtual Attr *clone(ASTContext &C) const { return ::new (C) IBOutletAttr; }
274
275  // Implement isa/cast/dyncast/etc.
276  static bool classof(const Attr *A) {
277    return A->getKind() == IBOutletKind;
278  }
279  static bool classof(const IBOutletAttr *A) { return true; }
280};
281
282DEF_SIMPLE_ATTR(NoReturn);
283DEF_SIMPLE_ATTR(AnalyzerNoReturn);
284DEF_SIMPLE_ATTR(Deprecated);
285
286class SectionAttr : public Attr {
287  std::string Name;
288public:
289  SectionAttr(const std::string &N) : Attr(Section), Name(N) {}
290
291  const std::string& getName() const { return Name; }
292
293  virtual Attr *clone(ASTContext &C) const { return ::new (C) SectionAttr(Name); }
294
295  // Implement isa/cast/dyncast/etc.
296  static bool classof(const Attr *A) {
297    return A->getKind() == Section;
298  }
299  static bool classof(const SectionAttr *A) { return true; }
300};
301
302DEF_SIMPLE_ATTR(Unavailable);
303DEF_SIMPLE_ATTR(Unused);
304DEF_SIMPLE_ATTR(Used);
305DEF_SIMPLE_ATTR(Weak);
306DEF_SIMPLE_ATTR(WeakImport);
307DEF_SIMPLE_ATTR(NoThrow);
308DEF_SIMPLE_ATTR(Const);
309DEF_SIMPLE_ATTR(Pure);
310
311class NonNullAttr : public Attr {
312  unsigned* ArgNums;
313  unsigned Size;
314public:
315  NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
316    ArgNums(0), Size(0) {
317
318    if (size == 0) return;
319    assert(arg_nums);
320    ArgNums = new unsigned[size];
321    Size = size;
322    memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
323  }
324
325  virtual ~NonNullAttr() {
326    delete [] ArgNums;
327  }
328
329  typedef const unsigned *iterator;
330  iterator begin() const { return ArgNums; }
331  iterator end() const { return ArgNums + Size; }
332  unsigned size() const { return Size; }
333
334  bool isNonNull(unsigned arg) const {
335    return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
336  }
337
338  virtual Attr *clone(ASTContext &C) const { return ::new (C) NonNullAttr(ArgNums, Size); }
339
340  static bool classof(const Attr *A) { return A->getKind() == NonNull; }
341  static bool classof(const NonNullAttr *A) { return true; }
342};
343
344class FormatAttr : public Attr {
345  std::string Type;
346  int formatIdx, firstArg;
347public:
348  FormatAttr(const std::string &type, int idx, int first) : Attr(Format),
349             Type(type), formatIdx(idx), firstArg(first) {}
350
351  const std::string& getType() const { return Type; }
352  void setType(const std::string &type) { Type = type; }
353  int getFormatIdx() const { return formatIdx; }
354  int getFirstArg() const { return firstArg; }
355
356  virtual Attr *clone(ASTContext &C) const {
357    return ::new (C) FormatAttr(Type, formatIdx, firstArg);
358  }
359
360  // Implement isa/cast/dyncast/etc.
361  static bool classof(const Attr *A) { return A->getKind() == Format; }
362  static bool classof(const FormatAttr *A) { return true; }
363};
364
365class VisibilityAttr : public Attr {
366public:
367  /// @brief An enumeration for the kinds of visibility of symbols.
368  enum VisibilityTypes {
369    DefaultVisibility = 0,
370    HiddenVisibility,
371    ProtectedVisibility
372  };
373private:
374  VisibilityTypes VisibilityType;
375public:
376  VisibilityAttr(VisibilityTypes v) : Attr(Visibility),
377                 VisibilityType(v) {}
378
379  VisibilityTypes getVisibility() const { return VisibilityType; }
380
381  virtual Attr *clone(ASTContext &C) const { return ::new (C) VisibilityAttr(VisibilityType); }
382
383  // Implement isa/cast/dyncast/etc.
384  static bool classof(const Attr *A) { return A->getKind() == Visibility; }
385  static bool classof(const VisibilityAttr *A) { return true; }
386};
387
388DEF_SIMPLE_ATTR(DLLImport);
389DEF_SIMPLE_ATTR(DLLExport);
390DEF_SIMPLE_ATTR(FastCall);
391DEF_SIMPLE_ATTR(StdCall);
392DEF_SIMPLE_ATTR(TransparentUnion);
393DEF_SIMPLE_ATTR(ObjCNSObject);
394DEF_SIMPLE_ATTR(ObjCException);
395
396class OverloadableAttr : public Attr {
397public:
398  OverloadableAttr() : Attr(Overloadable) { }
399
400  virtual bool isMerged() const { return false; }
401
402  virtual Attr *clone(ASTContext &C) const {
403    return ::new (C) OverloadableAttr;
404  }
405
406  static bool classof(const Attr *A) { return A->getKind() == Overloadable; }
407  static bool classof(const OverloadableAttr *) { return true; }
408};
409
410class BlocksAttr : public Attr {
411public:
412  enum BlocksAttrTypes {
413    ByRef = 0
414  };
415private:
416  BlocksAttrTypes BlocksAttrType;
417public:
418  BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {}
419
420  BlocksAttrTypes getType() const { return BlocksAttrType; }
421
422  virtual Attr *clone(ASTContext &C) const { return ::new (C) BlocksAttr(BlocksAttrType); }
423
424  // Implement isa/cast/dyncast/etc.
425  static bool classof(const Attr *A) { return A->getKind() == Blocks; }
426  static bool classof(const BlocksAttr *A) { return true; }
427};
428
429class FunctionDecl;
430
431class CleanupAttr : public Attr {
432  FunctionDecl *FD;
433
434public:
435  CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {}
436
437  const FunctionDecl *getFunctionDecl() const { return FD; }
438
439  virtual Attr *clone(ASTContext &C) const { return ::new (C) CleanupAttr(FD); }
440
441  // Implement isa/cast/dyncast/etc.
442  static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
443  static bool classof(const CleanupAttr *A) { return true; }
444};
445
446DEF_SIMPLE_ATTR(Nodebug);
447DEF_SIMPLE_ATTR(WarnUnusedResult);
448DEF_SIMPLE_ATTR(Noinline);
449
450class RegparmAttr : public Attr {
451  unsigned NumParams;
452
453public:
454  RegparmAttr(unsigned np) : Attr(Regparm), NumParams(np) {}
455
456  unsigned getNumParams() const { return NumParams; }
457
458  virtual Attr *clone(ASTContext &C) const {
459    return ::new (C) RegparmAttr(NumParams);
460  }
461
462  // Implement isa/cast/dyncast/etc.
463  static bool classof(const Attr *A) { return A->getKind() == Regparm; }
464  static bool classof(const RegparmAttr *A) { return true; }
465};
466
467// Checker-specific attributes.
468DEF_SIMPLE_ATTR(CFOwnershipRelease);
469DEF_SIMPLE_ATTR(NSOwnershipRelease);
470DEF_SIMPLE_ATTR(CFOwnershipRetain);
471DEF_SIMPLE_ATTR(NSOwnershipRetain);
472DEF_SIMPLE_ATTR(NSOwnershipReturns);
473
474#undef DEF_SIMPLE_ATTR
475
476}  // end namespace clang
477
478#endif
479