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