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