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