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