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