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