Attr.h revision 208954
1169691Skan//===--- Attr.h - Classes for representing expressions ----------*- C++ -*-===//
297403Sobrien//
397403Sobrien//                     The LLVM Compiler Infrastructure
497403Sobrien//
597403Sobrien// This file is distributed under the University of Illinois Open Source
697403Sobrien// License. See LICENSE.TXT for details.
797403Sobrien//
897403Sobrien//===----------------------------------------------------------------------===//
997403Sobrien//
1097403Sobrien//  This file defines the Attr interface and subclasses.
1197403Sobrien//
1297403Sobrien//===----------------------------------------------------------------------===//
1397403Sobrien
1497403Sobrien#ifndef LLVM_CLANG_AST_ATTR_H
1597403Sobrien#define LLVM_CLANG_AST_ATTR_H
1697403Sobrien
17169691Skan#include "llvm/Support/Casting.h"
1897403Sobrien#include "llvm/ADT/StringRef.h"
1997403Sobrien#include <cassert>
2097403Sobrien#include <cstring>
2197403Sobrien#include <algorithm>
2297403Sobrienusing llvm::dyn_cast;
2397403Sobrien
2497403Sobriennamespace clang {
2597403Sobrien  class ASTContext;
2697403Sobrien  class IdentifierInfo;
2797403Sobrien  class ObjCInterfaceDecl;
2897403Sobrien}
2997403Sobrien
3097403Sobrien// Defined in ASTContext.h
31132720Skanvoid *operator new(size_t Bytes, clang::ASTContext &C,
3297403Sobrien                   size_t Alignment = 16) throw ();
3397403Sobrien
3497403Sobrien// It is good practice to pair new/delete operators.  Also, MSVC gives many
35169691Skan// warnings if a matching delete overload is not declared, even though the
3697403Sobrien// throw() spec guarantees it will not be implicitly called.
37169691Skanvoid operator delete(void *Ptr, clang::ASTContext &C, size_t)
38107606Sobrien              throw ();
39169691Skan
40169691Skannamespace clang {
41169691Skan
42169691Skan/// Attr - This represents one attribute.
43169691Skanclass Attr {
44169691Skanpublic:
45169691Skan  enum Kind {
46169691Skan    Alias,
47169691Skan    Aligned,
48169691Skan    AlignMac68k,
49169691Skan    AlwaysInline,
50169691Skan    AnalyzerNoReturn, // Clang-specific.
51169691Skan    Annotate,
52169691Skan    AsmLabel, // Represent GCC asm label extension.
53169691Skan    BaseCheck,
54169691Skan    Blocks,
55169691Skan    CDecl,
56169691Skan    Cleanup,
57169691Skan    Const,
58169691Skan    Constructor,
5997403Sobrien    Deprecated,
6097403Sobrien    Destructor,
6197403Sobrien    FastCall,
6297403Sobrien    Final,
6397403Sobrien    Format,
6497403Sobrien    FormatArg,
6597403Sobrien    GNUInline,
6697403Sobrien    Hiding,
6797403Sobrien    IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
6897403Sobrien    IBOutletCollectionKind, // Clang-specific.
69132720Skan    IBActionKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
70132720Skan    Malloc,
7197403Sobrien    MaxFieldAlignment,
7297403Sobrien    NoDebug,
73132720Skan    NoInline,
74132720Skan    NonNull,
7597403Sobrien    NoReturn,
7697403Sobrien    NoThrow,
7797403Sobrien    ObjCException,
78132720Skan    ObjCNSObject,
79132720Skan    Override,
8097403Sobrien    CFReturnsRetained,      // Clang/Checker-specific.
8197403Sobrien    CFReturnsNotRetained,   // Clang/Checker-specific.
8297403Sobrien    NSReturnsRetained,      // Clang/Checker-specific.
83107606Sobrien    NSReturnsNotRetained,   // Clang/Checker-specific.
8497403Sobrien    Overloadable, // Clang-specific
8597403Sobrien    Packed,
8697403Sobrien    Pure,
87107606Sobrien    Regparm,
88107606Sobrien    ReqdWorkGroupSize,   // OpenCL-specific
89107606Sobrien    Section,
9097403Sobrien    Sentinel,
9197403Sobrien    StdCall,
9297403Sobrien    ThisCall,
93169691Skan    TransparentUnion,
94169691Skan    Unavailable,
95169691Skan    Unused,
96169691Skan    Used,
97169691Skan    Visibility,
98132720Skan    WarnUnusedResult,
99132720Skan    Weak,
100169691Skan    WeakImport,
101169691Skan    WeakRef,
102169691Skan
103169691Skan    FIRST_TARGET_ATTRIBUTE,
104169691Skan    DLLExport,
105169691Skan    DLLImport,
106132720Skan    MSP430Interrupt,
107169691Skan    X86ForceAlignArgPointer
108132720Skan  };
10997403Sobrien
11097403Sobrienprivate:
11197403Sobrien  Attr *Next;
11297403Sobrien  Kind AttrKind;
11397403Sobrien  bool Inherited : 1;
11497403Sobrien
11597403Sobrienprotected:
11697403Sobrien  void* operator new(size_t bytes) throw() {
11797403Sobrien    assert(0 && "Attrs cannot be allocated with regular 'new'.");
11897403Sobrien    return 0;
11997403Sobrien  }
12097403Sobrien  void operator delete(void* data) throw() {
12197403Sobrien    assert(0 && "Attrs cannot be released with regular 'delete'.");
12297403Sobrien  }
12397403Sobrien
124169691Skanprotected:
125169691Skan  Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
126169691Skan  virtual ~Attr() {
12797403Sobrien    assert(Next == 0 && "Destroy didn't work");
12897403Sobrien  }
12997403Sobrienpublic:
130169691Skan  virtual void Destroy(ASTContext &C);
131107606Sobrien
132117397Skan  /// \brief Whether this attribute should be merged to new
133107606Sobrien  /// declarations.
134132720Skan  virtual bool isMerged() const { return true; }
13597403Sobrien
136117397Skan  Kind getKind() const { return AttrKind; }
137107606Sobrien
138117397Skan  Attr *getNext() { return Next; }
139107606Sobrien  const Attr *getNext() const { return Next; }
14097403Sobrien  void setNext(Attr *next) { Next = next; }
14197403Sobrien
14297403Sobrien  template<typename T> const T *getNext() const {
14397403Sobrien    for (const Attr *attr = getNext(); attr; attr = attr->getNext())
14497403Sobrien      if (const T *V = dyn_cast<T>(attr))
14597403Sobrien        return V;
14697403Sobrien    return 0;
14797403Sobrien  }
14897403Sobrien
149241959Sdim  bool isInherited() const { return Inherited; }
15097403Sobrien  void setInherited(bool value) { Inherited = value; }
15197403Sobrien
15297403Sobrien  void addAttr(Attr *attr) {
15397403Sobrien    assert((attr != 0) && "addAttr(): attr is null");
15497403Sobrien
15597403Sobrien    // FIXME: This doesn't preserve the order in any way.
15697403Sobrien    attr->Next = Next;
15797403Sobrien    Next = attr;
15897403Sobrien  }
15997403Sobrien
16097403Sobrien  // Clone this attribute.
16197403Sobrien  virtual Attr* clone(ASTContext &C) const = 0;
16297403Sobrien
16397403Sobrien  // Implement isa/cast/dyncast/etc.
16497403Sobrien  static bool classof(const Attr *) { return true; }
16597403Sobrien};
16697403Sobrien
16797403Sobrienclass AttrWithString : public Attr {
16897403Sobrienprivate:
16997403Sobrien  const char *Str;
17097403Sobrien  unsigned StrLen;
171132720Skanprotected:
17297403Sobrien  AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s);
17397403Sobrien  llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
17497403Sobrien  void ReplaceString(ASTContext &C, llvm::StringRef newS);
17597403Sobrienpublic:
17697403Sobrien  virtual void Destroy(ASTContext &C);
17797403Sobrien};
17897403Sobrien
17997403Sobrien#define DEF_SIMPLE_ATTR(ATTR)                                           \
180132720Skanclass ATTR##Attr : public Attr {                                        \
181132720Skanpublic:                                                                 \
18297403Sobrien  ATTR##Attr() : Attr(ATTR) {}                                          \
18397403Sobrien  virtual Attr *clone(ASTContext &C) const;                             \
18497403Sobrien  static bool classof(const Attr *A) { return A->getKind() == ATTR; }   \
18597403Sobrien  static bool classof(const ATTR##Attr *A) { return true; }             \
18697403Sobrien}
187132720Skan
188132720SkanDEF_SIMPLE_ATTR(Packed);
189110614Skan
190132720Skan/// \brief Attribute for specifying a maximum field alignment; this is only
19197403Sobrien/// valid on record decls.
192132720Skanclass MaxFieldAlignmentAttr : public Attr {
193132720Skan  unsigned Alignment;
194132720Skan
19597403Sobrienpublic:
196132720Skan  MaxFieldAlignmentAttr(unsigned alignment)
197132720Skan    : Attr(MaxFieldAlignment), Alignment(alignment) {}
198132720Skan
199132720Skan  /// getAlignment - The specified alignment in bits.
200132720Skan  unsigned getAlignment() const { return Alignment; }
201132720Skan
20297403Sobrien  virtual Attr* clone(ASTContext &C) const;
203132720Skan
204132720Skan  // Implement isa/cast/dyncast/etc.
20597403Sobrien  static bool classof(const Attr *A) {
206132720Skan    return A->getKind() == MaxFieldAlignment;
207132720Skan  }
208132720Skan  static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
209132720Skan};
210132720Skan
21197403SobrienDEF_SIMPLE_ATTR(AlignMac68k);
212132720Skan
213132720Skanclass AlignedAttr : public Attr {
21497403Sobrien  unsigned Alignment;
215132720Skanpublic:
21697403Sobrien  AlignedAttr(unsigned alignment)
21797403Sobrien    : Attr(Aligned), Alignment(alignment) {}
218132720Skan
219132720Skan  /// getAlignment - The specified alignment in bits.
220132720Skan  unsigned getAlignment() const { return Alignment; }
22197403Sobrien
222132720Skan  /// getMaxAlignment - Get the maximum alignment of attributes on this list.
223132720Skan  unsigned getMaxAlignment() const {
22497403Sobrien    const AlignedAttr *Next = getNext<AlignedAttr>();
225132720Skan    if (Next)
226132720Skan      return std::max(Next->getMaxAlignment(), Alignment);
227132720Skan    else
228132720Skan      return Alignment;
229132720Skan  }
230132720Skan
231132720Skan  virtual Attr* clone(ASTContext &C) const;
232132720Skan
233132720Skan  // Implement isa/cast/dyncast/etc.
23497403Sobrien  static bool classof(const Attr *A) {
235132720Skan    return A->getKind() == Aligned;
236132720Skan  }
237132720Skan  static bool classof(const AlignedAttr *A) { return true; }
238132720Skan};
239132720Skan
240132720Skanclass AnnotateAttr : public AttrWithString {
241132720Skanpublic:
242132720Skan  AnnotateAttr(ASTContext &C, llvm::StringRef ann)
243132720Skan    : AttrWithString(Annotate, C, ann) {}
244132720Skan
245132720Skan  llvm::StringRef getAnnotation() const { return getString(); }
246132720Skan
247132720Skan  virtual Attr* clone(ASTContext &C) const;
248132720Skan
249132720Skan  // Implement isa/cast/dyncast/etc.
250132720Skan  static bool classof(const Attr *A) {
251132720Skan    return A->getKind() == Annotate;
25297403Sobrien  }
253132720Skan  static bool classof(const AnnotateAttr *A) { return true; }
254132720Skan};
255132720Skan
256132720Skanclass AsmLabelAttr : public AttrWithString {
257132720Skanpublic:
258132720Skan  AsmLabelAttr(ASTContext &C, llvm::StringRef L)
259132720Skan    : AttrWithString(AsmLabel, C, L) {}
260132720Skan
261132720Skan  llvm::StringRef getLabel() const { return getString(); }
262132720Skan
263132720Skan  virtual Attr* clone(ASTContext &C) const;
264132720Skan
265132720Skan  // Implement isa/cast/dyncast/etc.
266132720Skan  static bool classof(const Attr *A) {
267132720Skan    return A->getKind() == AsmLabel;
268132720Skan  }
269132720Skan  static bool classof(const AsmLabelAttr *A) { return true; }
270132720Skan};
271132720Skan
272117397SkanDEF_SIMPLE_ATTR(AlwaysInline);
273169691Skan
274169691Skanclass AliasAttr : public AttrWithString {
275169691Skanpublic:
276132720Skan  AliasAttr(ASTContext &C, llvm::StringRef aliasee)
277169691Skan    : AttrWithString(Alias, C, aliasee) {}
278169691Skan
279169691Skan  llvm::StringRef getAliasee() const { return getString(); }
280132720Skan
281132720Skan  virtual Attr *clone(ASTContext &C) const;
282132720Skan
283132720Skan  // Implement isa/cast/dyncast/etc.
284132720Skan  static bool classof(const Attr *A) { return A->getKind() == Alias; }
285132720Skan  static bool classof(const AliasAttr *A) { return true; }
286132720Skan};
287132720Skan
288117397Skanclass ConstructorAttr : public Attr {
289132720Skan  int priority;
290132720Skanpublic:
291132720Skan  ConstructorAttr(int p) : Attr(Constructor), priority(p) {}
292132720Skan
293132720Skan  int getPriority() const { return priority; }
294132720Skan
295132720Skan  virtual Attr *clone(ASTContext &C) const;
29697403Sobrien
29797403Sobrien  // Implement isa/cast/dyncast/etc.
29897403Sobrien  static bool classof(const Attr *A) { return A->getKind() == Constructor; }
299132720Skan  static bool classof(const ConstructorAttr *A) { return true; }
300132720Skan};
30197403Sobrien
302132720Skanclass DestructorAttr : public Attr {
303132720Skan  int priority;
304132720Skanpublic:
305132720Skan  DestructorAttr(int p) : Attr(Destructor), priority(p) {}
306132720Skan
307132720Skan  int getPriority() const { return priority; }
30897403Sobrien
309132720Skan  virtual Attr *clone(ASTContext &C) const;
310132720Skan
311132720Skan  // Implement isa/cast/dyncast/etc.
312132720Skan  static bool classof(const Attr *A) { return A->getKind() == Destructor; }
313132720Skan  static bool classof(const DestructorAttr *A) { return true; }
314132720Skan};
315132720Skan
31697403Sobrienclass IBOutletAttr : public Attr {
317132720Skanpublic:
318132720Skan  IBOutletAttr() : Attr(IBOutletKind) {}
319132720Skan
320132720Skan  virtual Attr *clone(ASTContext &C) const;
321132720Skan
322132720Skan  // Implement isa/cast/dyncast/etc.
323132720Skan  static bool classof(const Attr *A) {
324132720Skan    return A->getKind() == IBOutletKind;
325132720Skan  }
326132720Skan  static bool classof(const IBOutletAttr *A) { return true; }
327132720Skan};
328132720Skan
329132720Skanclass IBOutletCollectionAttr : public Attr {
330132720Skan  const ObjCInterfaceDecl *D;
331132720Skanpublic:
332132720Skan  IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0)
333132720Skan    : Attr(IBOutletCollectionKind), D(d) {}
334132720Skan
335132720Skan  const ObjCInterfaceDecl *getClass() const { return D; }
336132720Skan
337132720Skan  virtual Attr *clone(ASTContext &C) const;
338132720Skan
339132720Skan  // Implement isa/cast/dyncast/etc.
340132720Skan  static bool classof(const Attr *A) {
341132720Skan    return A->getKind() == IBOutletCollectionKind;
342132720Skan  }
343132720Skan  static bool classof(const IBOutletCollectionAttr *A) { return true; }
344132720Skan};
345132720Skan
346132720Skanclass IBActionAttr : public Attr {
347132720Skanpublic:
348132720Skan  IBActionAttr() : Attr(IBActionKind) {}
349132720Skan
350132720Skan  virtual Attr *clone(ASTContext &C) const;
351132720Skan
352132720Skan    // Implement isa/cast/dyncast/etc.
353132720Skan  static bool classof(const Attr *A) {
354132720Skan    return A->getKind() == IBActionKind;
355132720Skan  }
356132720Skan  static bool classof(const IBActionAttr *A) { return true; }
357132720Skan};
358132720Skan
359132720SkanDEF_SIMPLE_ATTR(AnalyzerNoReturn);
360132720SkanDEF_SIMPLE_ATTR(Deprecated);
361132720SkanDEF_SIMPLE_ATTR(Final);
362132720SkanDEF_SIMPLE_ATTR(GNUInline);
363132720SkanDEF_SIMPLE_ATTR(Malloc);
364132720SkanDEF_SIMPLE_ATTR(NoReturn);
365132720Skan
366132720Skanclass SectionAttr : public AttrWithString {
367132720Skanpublic:
368132720Skan  SectionAttr(ASTContext &C, llvm::StringRef N)
369132720Skan    : AttrWithString(Section, C, N) {}
370132720Skan
371132720Skan  llvm::StringRef getName() const { return getString(); }
372132720Skan
373132720Skan  virtual Attr *clone(ASTContext &C) const;
374132720Skan
375132720Skan  // Implement isa/cast/dyncast/etc.
376132720Skan  static bool classof(const Attr *A) {
377132720Skan    return A->getKind() == Section;
378132720Skan  }
379132720Skan  static bool classof(const SectionAttr *A) { return true; }
380132720Skan};
381132720Skan
382132720SkanDEF_SIMPLE_ATTR(Unavailable);
383132720SkanDEF_SIMPLE_ATTR(Unused);
384132720SkanDEF_SIMPLE_ATTR(Used);
385132720SkanDEF_SIMPLE_ATTR(Weak);
38697403SobrienDEF_SIMPLE_ATTR(WeakImport);
387132720SkanDEF_SIMPLE_ATTR(WeakRef);
388169691SkanDEF_SIMPLE_ATTR(NoThrow);
389169691SkanDEF_SIMPLE_ATTR(Const);
390169691SkanDEF_SIMPLE_ATTR(Pure);
391169691Skan
392169691Skanclass NonNullAttr : public Attr {
393169691Skan  unsigned* ArgNums;
394169691Skan  unsigned Size;
395169691Skanpublic:
396169691Skan  NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
397169691Skan
398169691Skan  virtual void Destroy(ASTContext &C);
399169691Skan
400169691Skan  typedef const unsigned *iterator;
401169691Skan  iterator begin() const { return ArgNums; }
402169691Skan  iterator end() const { return ArgNums + Size; }
403169691Skan  unsigned size() const { return Size; }
404132720Skan
405132720Skan  bool isNonNull(unsigned arg) const {
406132720Skan    return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
407132720Skan  }
408132720Skan
409132720Skan  virtual Attr *clone(ASTContext &C) const;
410132720Skan
411132720Skan  static bool classof(const Attr *A) { return A->getKind() == NonNull; }
412132720Skan  static bool classof(const NonNullAttr *A) { return true; }
413169691Skan};
414169691Skan
415169691Skanclass FormatAttr : public AttrWithString {
416169691Skan  int formatIdx, firstArg;
417169691Skanpublic:
418169691Skan  FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
419169691Skan    : AttrWithString(Format, C, type), formatIdx(idx), firstArg(first) {}
420169691Skan
421169691Skan  llvm::StringRef getType() const { return getString(); }
422169691Skan  void setType(ASTContext &C, llvm::StringRef type);
423169691Skan  int getFormatIdx() const { return formatIdx; }
424169691Skan  int getFirstArg() const { return firstArg; }
425169691Skan
426169691Skan  virtual Attr *clone(ASTContext &C) const;
427169691Skan
428169691Skan  // Implement isa/cast/dyncast/etc.
429169691Skan  static bool classof(const Attr *A) { return A->getKind() == Format; }
430169691Skan  static bool classof(const FormatAttr *A) { return true; }
431169691Skan};
432169691Skan
433169691Skanclass FormatArgAttr : public Attr {
434169691Skan  int formatIdx;
435169691Skanpublic:
436169691Skan  FormatArgAttr(int idx) : Attr(FormatArg), formatIdx(idx) {}
437132720Skan  int getFormatIdx() const { return formatIdx; }
438132720Skan
43997403Sobrien  virtual Attr *clone(ASTContext &C) const;
440169691Skan
441  // Implement isa/cast/dyncast/etc.
442  static bool classof(const Attr *A) { return A->getKind() == FormatArg; }
443  static bool classof(const FormatArgAttr *A) { return true; }
444};
445
446class SentinelAttr : public Attr {
447  int sentinel, NullPos;
448public:
449  SentinelAttr(int sentinel_val, int nullPos) : Attr(Sentinel),
450               sentinel(sentinel_val), NullPos(nullPos) {}
451  int getSentinel() const { return sentinel; }
452  int getNullPos() const { return NullPos; }
453
454  virtual Attr *clone(ASTContext &C) const;
455
456  // Implement isa/cast/dyncast/etc.
457  static bool classof(const Attr *A) { return A->getKind() == Sentinel; }
458  static bool classof(const SentinelAttr *A) { return true; }
459};
460
461class VisibilityAttr : public Attr {
462public:
463  /// @brief An enumeration for the kinds of visibility of symbols.
464  enum VisibilityTypes {
465    DefaultVisibility = 0,
466    HiddenVisibility,
467    ProtectedVisibility
468  };
469private:
470  VisibilityTypes VisibilityType;
471public:
472  VisibilityAttr(VisibilityTypes v) : Attr(Visibility),
473                 VisibilityType(v) {}
474
475  VisibilityTypes getVisibility() const { return VisibilityType; }
476
477  virtual Attr *clone(ASTContext &C) const;
478
479  // Implement isa/cast/dyncast/etc.
480  static bool classof(const Attr *A) { return A->getKind() == Visibility; }
481  static bool classof(const VisibilityAttr *A) { return true; }
482};
483
484DEF_SIMPLE_ATTR(FastCall);
485DEF_SIMPLE_ATTR(StdCall);
486DEF_SIMPLE_ATTR(ThisCall);
487DEF_SIMPLE_ATTR(CDecl);
488DEF_SIMPLE_ATTR(TransparentUnion);
489DEF_SIMPLE_ATTR(ObjCNSObject);
490DEF_SIMPLE_ATTR(ObjCException);
491
492class OverloadableAttr : public Attr {
493public:
494  OverloadableAttr() : Attr(Overloadable) { }
495
496  virtual bool isMerged() const { return false; }
497
498  virtual Attr *clone(ASTContext &C) const;
499
500  static bool classof(const Attr *A) { return A->getKind() == Overloadable; }
501  static bool classof(const OverloadableAttr *) { return true; }
502};
503
504class BlocksAttr : public Attr {
505public:
506  enum BlocksAttrTypes {
507    ByRef = 0
508  };
509private:
510  BlocksAttrTypes BlocksAttrType;
511public:
512  BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {}
513
514  BlocksAttrTypes getType() const { return BlocksAttrType; }
515
516  virtual Attr *clone(ASTContext &C) const;
517
518  // Implement isa/cast/dyncast/etc.
519  static bool classof(const Attr *A) { return A->getKind() == Blocks; }
520  static bool classof(const BlocksAttr *A) { return true; }
521};
522
523class FunctionDecl;
524
525class CleanupAttr : public Attr {
526  FunctionDecl *FD;
527
528public:
529  CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {}
530
531  const FunctionDecl *getFunctionDecl() const { return FD; }
532
533  virtual Attr *clone(ASTContext &C) const;
534
535  // Implement isa/cast/dyncast/etc.
536  static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
537  static bool classof(const CleanupAttr *A) { return true; }
538};
539
540DEF_SIMPLE_ATTR(NoDebug);
541DEF_SIMPLE_ATTR(WarnUnusedResult);
542DEF_SIMPLE_ATTR(NoInline);
543
544class RegparmAttr : public Attr {
545  unsigned NumParams;
546
547public:
548  RegparmAttr(unsigned np) : Attr(Regparm), NumParams(np) {}
549
550  unsigned getNumParams() const { return NumParams; }
551
552  virtual Attr *clone(ASTContext &C) const;
553
554  // Implement isa/cast/dyncast/etc.
555  static bool classof(const Attr *A) { return A->getKind() == Regparm; }
556  static bool classof(const RegparmAttr *A) { return true; }
557};
558
559class ReqdWorkGroupSizeAttr : public Attr {
560  unsigned X, Y, Z;
561public:
562  ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
563  : Attr(ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
564
565  unsigned getXDim() const { return X; }
566  unsigned getYDim() const { return Y; }
567  unsigned getZDim() const { return Z; }
568
569  virtual Attr *clone(ASTContext &C) const;
570
571  // Implement isa/cast/dyncast/etc.
572  static bool classof(const Attr *A) {
573    return A->getKind() == ReqdWorkGroupSize;
574  }
575  static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
576};
577
578// Checker-specific attributes.
579DEF_SIMPLE_ATTR(CFReturnsNotRetained);
580DEF_SIMPLE_ATTR(CFReturnsRetained);
581DEF_SIMPLE_ATTR(NSReturnsNotRetained);
582DEF_SIMPLE_ATTR(NSReturnsRetained);
583
584// C++0x member checking attributes.
585DEF_SIMPLE_ATTR(BaseCheck);
586DEF_SIMPLE_ATTR(Hiding);
587DEF_SIMPLE_ATTR(Override);
588
589// Target-specific attributes
590DEF_SIMPLE_ATTR(DLLImport);
591DEF_SIMPLE_ATTR(DLLExport);
592
593class MSP430InterruptAttr : public Attr {
594  unsigned Number;
595
596public:
597  MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {}
598
599  unsigned getNumber() const { return Number; }
600
601  virtual Attr *clone(ASTContext &C) const;
602
603  // Implement isa/cast/dyncast/etc.
604  static bool classof(const Attr *A) { return A->getKind() == MSP430Interrupt; }
605  static bool classof(const MSP430InterruptAttr *A) { return true; }
606};
607
608DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
609
610#undef DEF_SIMPLE_ATTR
611
612}  // end namespace clang
613
614#endif
615