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