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