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