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