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