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