AttributeList.h revision 0a0d2b179085a52c10402feebeb6db8b4d96a140
1//===--- AttributeList.h - Parsed attribute sets ----------------*- 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 AttributeList class, which is used to collect 11// parsed attributes. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_SEMA_ATTRLIST_H 16#define LLVM_CLANG_SEMA_ATTRLIST_H 17 18#include "llvm/Support/Allocator.h" 19#include "clang/Sema/Ownership.h" 20#include "clang/Basic/SourceLocation.h" 21#include "clang/Basic/VersionTuple.h" 22#include "clang/AST/Expr.h" 23#include <cassert> 24 25namespace clang { 26 class IdentifierInfo; 27 class Expr; 28 29/// \brief Represents information about a change in availability for 30/// an entity, which is part of the encoding of the 'availability' 31/// attribute. 32struct AvailabilityChange { 33 /// \brief The location of the keyword indicating the kind of change. 34 SourceLocation KeywordLoc; 35 36 /// \brief The version number at which the change occurred. 37 VersionTuple Version; 38 39 /// \brief The source range covering the version number. 40 SourceRange VersionRange; 41 42 /// \brief Determine whether this availability change is valid. 43 bool isValid() const { return !Version.empty(); } 44}; 45 46/// AttributeList - Represents GCC's __attribute__ declaration. There are 47/// 4 forms of this construct...they are: 48/// 49/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused. 50/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused. 51/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used. 52/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used. 53/// 54class AttributeList { 55public: 56 class Factory; 57private: 58 IdentifierInfo *AttrName; 59 SourceLocation AttrLoc; 60 IdentifierInfo *ScopeName; 61 SourceLocation ScopeLoc; 62 IdentifierInfo *ParmName; 63 SourceLocation ParmLoc; 64 Expr **Args; 65 unsigned NumArgs; 66 AttributeList *Next; 67 bool DeclspecAttribute, CXX0XAttribute; 68 69 // For the 'availability' attribute. 70 AvailabilityChange AvailabilityIntroduced; 71 AvailabilityChange AvailabilityDeprecated; 72 AvailabilityChange AvailabilityObsoleted; 73 74 /// True if already diagnosed as invalid. 75 mutable bool Invalid; 76 77 AttributeList(const AttributeList &); // DO NOT IMPLEMENT 78 void operator=(const AttributeList &); // DO NOT IMPLEMENT 79 void operator delete(void *); // DO NOT IMPLEMENT 80 ~AttributeList(); // DO NOT IMPLEMENT 81 AttributeList(llvm::BumpPtrAllocator &Alloc, 82 IdentifierInfo *AttrName, SourceLocation AttrLoc, 83 IdentifierInfo *ScopeName, SourceLocation ScopeLoc, 84 IdentifierInfo *ParmName, SourceLocation ParmLoc, 85 Expr **args, unsigned numargs, 86 bool declspec, bool cxx0x); 87 88 AttributeList(llvm::BumpPtrAllocator &Alloc, 89 IdentifierInfo *AttrName, SourceLocation AttrLoc, 90 IdentifierInfo *ScopeName, SourceLocation ScopeLoc, 91 IdentifierInfo *ParmName, SourceLocation ParmLoc, 92 const AvailabilityChange &Introduced, 93 const AvailabilityChange &Deprecated, 94 const AvailabilityChange &Obsoleted, 95 bool declspec, bool cxx0x); 96public: 97 class Factory { 98 llvm::BumpPtrAllocator Alloc; 99 public: 100 Factory() {} 101 ~Factory() {} 102 AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc, 103 IdentifierInfo *ScopeName, SourceLocation ScopeLoc, 104 IdentifierInfo *ParmName, SourceLocation ParmLoc, 105 Expr **args, unsigned numargs, bool declspec = false, bool cxx0x = false) { 106 AttributeList *Mem = Alloc.Allocate<AttributeList>(); 107 new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc, 108 ParmName, ParmLoc, args, numargs, 109 declspec, cxx0x); 110 return Mem; 111 } 112 113 AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc, 114 IdentifierInfo *ScopeName, SourceLocation ScopeLoc, 115 IdentifierInfo *ParmName, SourceLocation ParmLoc, 116 const AvailabilityChange &Introduced, 117 const AvailabilityChange &Deprecated, 118 const AvailabilityChange &Obsoleted, 119 bool declspec = false, bool cxx0x = false) { 120 AttributeList *Mem = Alloc.Allocate<AttributeList>(); 121 new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc, 122 ParmName, ParmLoc, Introduced, Deprecated, 123 Obsoleted, declspec, cxx0x); 124 return Mem; 125 } 126 127 AttributeList* CreateIntegerAttribute(ASTContext &C, IdentifierInfo *Name, 128 SourceLocation TokLoc, int Arg) { 129 Expr* IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t)Arg), 130 C.IntTy, TokLoc); 131 return Create( Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 0); 132 } 133 }; 134 135 enum Kind { // Please keep this list alphabetized. 136 AT_IBAction, // Clang-specific. 137 AT_IBOutlet, // Clang-specific. 138 AT_IBOutletCollection, // Clang-specific. 139 AT_address_space, 140 AT_alias, 141 AT_aligned, 142 AT_always_inline, 143 AT_analyzer_noreturn, 144 AT_annotate, 145 AT_availability, // Clang-specific 146 AT_base_check, 147 AT_blocks, 148 AT_carries_dependency, 149 AT_cdecl, 150 AT_cleanup, 151 AT_common, 152 AT_const, 153 AT_constant, 154 AT_constructor, 155 AT_deprecated, 156 AT_destructor, 157 AT_device, 158 AT_dllexport, 159 AT_dllimport, 160 AT_ext_vector_type, 161 AT_fastcall, 162 AT_format, 163 AT_format_arg, 164 AT_global, 165 AT_gnu_inline, 166 AT_host, 167 AT_launch_bounds, 168 AT_malloc, 169 AT_may_alias, 170 AT_mode, 171 AT_neon_polyvector_type, // Clang-specific. 172 AT_neon_vector_type, // Clang-specific. 173 AT_naked, 174 AT_nodebug, 175 AT_noinline, 176 AT_no_instrument_function, 177 AT_nocommon, 178 AT_nonnull, 179 AT_noreturn, 180 AT_nothrow, 181 AT_nsobject, 182 AT_objc_exception, 183 AT_objc_method_family, 184 AT_cf_returns_not_retained, // Clang-specific. 185 AT_cf_returns_retained, // Clang-specific. 186 AT_ns_returns_not_retained, // Clang-specific. 187 AT_ns_returns_retained, // Clang-specific. 188 AT_ns_returns_autoreleased, // Clang-specific. 189 AT_cf_consumed, // Clang-specific. 190 AT_ns_consumed, // Clang-specific. 191 AT_ns_consumes_self, // Clang-specific. 192 AT_objc_gc, 193 AT_opencl_image_access, // OpenCL-specific. 194 AT_opencl_kernel_function, // OpenCL-specific. 195 AT_overloadable, // Clang-specific. 196 AT_ownership_holds, // Clang-specific. 197 AT_ownership_returns, // Clang-specific. 198 AT_ownership_takes, // Clang-specific. 199 AT_packed, 200 AT_pascal, 201 AT_pure, 202 AT_regparm, 203 AT_section, 204 AT_sentinel, 205 AT_shared, 206 AT_stdcall, 207 AT_thiscall, 208 AT_transparent_union, 209 AT_unavailable, 210 AT_unused, 211 AT_used, 212 AT_uuid, 213 AT_vecreturn, // PS3 PPU-specific. 214 AT_vector_size, 215 AT_visibility, 216 AT_warn_unused_result, 217 AT_weak, 218 AT_weakref, 219 AT_weak_import, 220 AT_reqd_wg_size, 221 AT_init_priority, 222 IgnoredAttribute, 223 UnknownAttribute 224 }; 225 226 IdentifierInfo *getName() const { return AttrName; } 227 SourceLocation getLoc() const { return AttrLoc; } 228 229 bool hasScope() const { return ScopeName; } 230 IdentifierInfo *getScopeName() const { return ScopeName; } 231 SourceLocation getScopeLoc() const { return ScopeLoc; } 232 233 IdentifierInfo *getParameterName() const { return ParmName; } 234 SourceLocation getParameterLoc() const { return ParmLoc; } 235 236 bool isDeclspecAttribute() const { return DeclspecAttribute; } 237 bool isCXX0XAttribute() const { return CXX0XAttribute; } 238 239 bool isInvalid() const { return Invalid; } 240 void setInvalid(bool b = true) const { Invalid = b; } 241 242 Kind getKind() const { return getKind(getName()); } 243 static Kind getKind(const IdentifierInfo *Name); 244 245 AttributeList *getNext() const { return Next; } 246 void setNext(AttributeList *N) { Next = N; } 247 248 /// getNumArgs - Return the number of actual arguments to this attribute. 249 unsigned getNumArgs() const { return NumArgs; } 250 251 /// getArg - Return the specified argument. 252 Expr *getArg(unsigned Arg) const { 253 assert(Arg < NumArgs && "Arg access out of range!"); 254 return Args[Arg]; 255 } 256 257 class arg_iterator { 258 Expr** X; 259 unsigned Idx; 260 public: 261 arg_iterator(Expr** x, unsigned idx) : X(x), Idx(idx) {} 262 263 arg_iterator& operator++() { 264 ++Idx; 265 return *this; 266 } 267 268 bool operator==(const arg_iterator& I) const { 269 assert (X == I.X && 270 "compared arg_iterators are for different argument lists"); 271 return Idx == I.Idx; 272 } 273 274 bool operator!=(const arg_iterator& I) const { 275 return !operator==(I); 276 } 277 278 Expr* operator*() const { 279 return X[Idx]; 280 } 281 282 unsigned getArgNum() const { 283 return Idx+1; 284 } 285 }; 286 287 arg_iterator arg_begin() const { 288 return arg_iterator(Args, 0); 289 } 290 291 arg_iterator arg_end() const { 292 return arg_iterator(Args, NumArgs); 293 } 294 295 const AvailabilityChange &getAvailabilityIntroduced() const { 296 assert(getKind() == AT_availability && "Not an availability attribute"); 297 return AvailabilityIntroduced; 298 } 299 300 const AvailabilityChange &getAvailabilityDeprecated() const { 301 assert(getKind() == AT_availability && "Not an availability attribute"); 302 return AvailabilityDeprecated; 303 } 304 305 const AvailabilityChange &getAvailabilityObsoleted() const { 306 assert(getKind() == AT_availability && "Not an availability attribute"); 307 return AvailabilityObsoleted; 308 } 309}; 310 311/// addAttributeLists - Add two AttributeLists together 312/// The right-hand list is appended to the left-hand list, if any 313/// A pointer to the joined list is returned. 314/// Note: the lists are not left unmodified. 315inline AttributeList *addAttributeLists(AttributeList *Left, 316 AttributeList *Right) { 317 if (!Left) 318 return Right; 319 320 AttributeList *next = Left, *prev; 321 do { 322 prev = next; 323 next = next->getNext(); 324 } while (next); 325 prev->setNext(Right); 326 return Left; 327} 328 329/// CXX0XAttributeList - A wrapper around a C++0x attribute list. 330/// Stores, in addition to the list proper, whether or not an actual list was 331/// (as opposed to an empty list, which may be ill-formed in some places) and 332/// the source range of the list. 333struct CXX0XAttributeList { 334 AttributeList *AttrList; 335 SourceRange Range; 336 bool HasAttr; 337 CXX0XAttributeList (AttributeList *attrList, SourceRange range, bool hasAttr) 338 : AttrList(attrList), Range(range), HasAttr (hasAttr) { 339 } 340 CXX0XAttributeList () 341 : AttrList(0), Range(), HasAttr(false) { 342 } 343}; 344 345/// ParsedAttributes - A collection of parsed attributes. Currently 346/// we don't differentiate between the various attribute syntaxes, 347/// which is basically silly. 348/// 349/// Right now this is a very lightweight container, but the expectation 350/// is that this will become significantly more serious. 351class ParsedAttributes { 352public: 353 ParsedAttributes() : list(0) {} 354 355 bool empty() const { return list == 0; } 356 357 void add(AttributeList *newAttr) { 358 assert(newAttr); 359 assert(newAttr->getNext() == 0); 360 newAttr->setNext(list); 361 list = newAttr; 362 } 363 364 void append(AttributeList *newList) { 365 if (!newList) return; 366 367 AttributeList *lastInNewList = newList; 368 while (AttributeList *next = lastInNewList->getNext()) 369 lastInNewList = next; 370 371 lastInNewList->setNext(list); 372 list = newList; 373 } 374 375 void set(AttributeList *newList) { 376 list = newList; 377 } 378 379 void clear() { list = 0; } 380 AttributeList *getList() const { return list; } 381 382 /// Returns a reference to the attribute list. Try not to introduce 383 /// dependencies on this method, it may not be long-lived. 384 AttributeList *&getListRef() { return list; } 385 386private: 387 AttributeList *list; 388}; 389 390} // end namespace clang 391 392#endif 393