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