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