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