AttributeList.h revision 686775deca8b8685eb90801495880e3abdd844c2
16a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek//===--- AttributeList.h - Parsed attribute sets ----------------*- C++ -*-===// 26a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// 36a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// The LLVM Compiler Infrastructure 46a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// 56a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// This file is distributed under the University of Illinois Open Source 66a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// License. See LICENSE.TXT for details. 76a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// 86a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek//===----------------------------------------------------------------------===// 96a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// 106a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// This file defines the AttributeList class, which is used to collect 116a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// parsed attributes. 126a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek// 136a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek//===----------------------------------------------------------------------===// 146a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek 156a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek#ifndef LLVM_CLANG_SEMA_ATTRLIST_H 166a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek#define LLVM_CLANG_SEMA_ATTRLIST_H 173245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner 186a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek#include "llvm/Support/Allocator.h" 1957df3b950061c73d13d3116f747e79d7955a216aChris Lattner#include "llvm/ADT/SmallVector.h" 206a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek#include "clang/Basic/SourceLocation.h" 216a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek#include "clang/Basic/VersionTuple.h" 226a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek#include <cassert> 236a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek 249402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattnernamespace clang { 255ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner class ASTContext; 265ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner class IdentifierInfo; 275ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner class Expr; 285ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner 295ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// \brief Represents information about a change in availability for 305ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// an entity, which is part of the encoding of the 'availability' 315ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// attribute. 325ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattnerstruct AvailabilityChange { 335ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner /// \brief The location of the keyword indicating the kind of change. 345ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner SourceLocation KeywordLoc; 355ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner 365ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner /// \brief The version number at which the change occurred. 375ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner VersionTuple Version; 385ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner 395ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner /// \brief The source range covering the version number. 405ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner SourceRange VersionRange; 415ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner 425ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner /// \brief Determine whether this availability change is valid. 435ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner bool isValid() const { return !Version.empty(); } 445ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner}; 455ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner 465ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// AttributeList - Represents GCC's __attribute__ declaration. There are 475ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// 4 forms of this construct...they are: 485ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// 495ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused. 505ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused. 515ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used. 529402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used. 535ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// 545ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattnerclass AttributeList { // TODO: This should really be called ParsedAttribute 555ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattnerprivate: 569402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner IdentifierInfo *AttrName; 579402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner IdentifierInfo *ScopeName; 589402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner IdentifierInfo *ParmName; 599402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner SourceLocation AttrLoc; 609402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner SourceLocation ScopeLoc; 619402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner SourceLocation ParmLoc; 629402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 639402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// The number of expression arguments this attribute has. 649402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// The expressions themselves are stored after the object. 659402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner unsigned NumArgs : 16; 669402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 679402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// True if Microsoft style: declspec(foo). 689402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner unsigned DeclspecAttribute : 1; 699402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 709402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// True if C++0x-style: [[foo]]. 719402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner unsigned CXX0XAttribute : 1; 729402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 739402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// True if already diagnosed as invalid. 749402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner mutable unsigned Invalid : 1; 759402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 769402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// True if this has the extra information associated with an 779402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// availability attribute. 789402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner unsigned IsAvailability : 1; 799402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 809402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner unsigned AttrKind : 8; 819402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 829402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// \brief The location of the 'unavailable' keyword in an 839402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// availability attribute. 849402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner SourceLocation UnavailableLoc; 859402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 869402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// The next attribute in the current position. 879402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner AttributeList *NextInPosition; 889402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 899402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner /// The next attribute allocated in the current Pool. 909402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner AttributeList *NextInPool; 919402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner 929402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner Expr **getArgsBuffer() { 939402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner return reinterpret_cast<Expr**>(this+1); 949402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner } 959402b57a0dca4058fe56d7fd84e97fc496421125Chris Lattner Expr * const *getArgsBuffer() const { 965ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner return reinterpret_cast<Expr* const *>(this+1); 975ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner } 98fa5be3617294f0e3c341f0ecb6b2076478b1b5acTed Kremenek 99fa5be3617294f0e3c341f0ecb6b2076478b1b5acTed Kremenek enum AvailabilitySlot { 1006a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek IntroducedSlot, DeprecatedSlot, ObsoletedSlot 1016a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek }; 1026a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek 1036a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { 1046a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek return reinterpret_cast<AvailabilityChange*>(this+1)[index]; 1056a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek } 1066a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const { 107735271479ac57c27f744806859efd5b001dea248Chris Lattner return reinterpret_cast<const AvailabilityChange*>(this+1)[index]; 108735271479ac57c27f744806859efd5b001dea248Chris Lattner } 1096a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek 11049cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AttributeList(const AttributeList &); // DO NOT IMPLEMENT 1116a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek void operator=(const AttributeList &); // DO NOT IMPLEMENT 112735271479ac57c27f744806859efd5b001dea248Chris Lattner void operator delete(void *); // DO NOT IMPLEMENT 113735271479ac57c27f744806859efd5b001dea248Chris Lattner ~AttributeList(); // DO NOT IMPLEMENT 114735271479ac57c27f744806859efd5b001dea248Chris Lattner 115735271479ac57c27f744806859efd5b001dea248Chris Lattner size_t allocated_size() const; 116735271479ac57c27f744806859efd5b001dea248Chris Lattner 117735271479ac57c27f744806859efd5b001dea248Chris Lattner AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc, 1186a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek IdentifierInfo *scopeName, SourceLocation scopeLoc, 119735271479ac57c27f744806859efd5b001dea248Chris Lattner IdentifierInfo *parmName, SourceLocation parmLoc, 120735271479ac57c27f744806859efd5b001dea248Chris Lattner Expr **args, unsigned numArgs, 12149cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek bool declspec, bool cxx0x) 122735271479ac57c27f744806859efd5b001dea248Chris Lattner : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), 1236f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc), 124735271479ac57c27f744806859efd5b001dea248Chris Lattner NumArgs(numArgs), 1256f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false), 126735271479ac57c27f744806859efd5b001dea248Chris Lattner IsAvailability(false), NextInPosition(0), NextInPool(0) { 127735271479ac57c27f744806859efd5b001dea248Chris Lattner if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); 128735271479ac57c27f744806859efd5b001dea248Chris Lattner AttrKind = getKind(getName()); 129735271479ac57c27f744806859efd5b001dea248Chris Lattner } 130735271479ac57c27f744806859efd5b001dea248Chris Lattner 131735271479ac57c27f744806859efd5b001dea248Chris Lattner AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc, 132735271479ac57c27f744806859efd5b001dea248Chris Lattner IdentifierInfo *scopeName, SourceLocation scopeLoc, 133735271479ac57c27f744806859efd5b001dea248Chris Lattner IdentifierInfo *parmName, SourceLocation parmLoc, 134735271479ac57c27f744806859efd5b001dea248Chris Lattner const AvailabilityChange &introduced, 135735271479ac57c27f744806859efd5b001dea248Chris Lattner const AvailabilityChange &deprecated, 136735271479ac57c27f744806859efd5b001dea248Chris Lattner const AvailabilityChange &obsoleted, 137735271479ac57c27f744806859efd5b001dea248Chris Lattner SourceLocation unavailable, 138735271479ac57c27f744806859efd5b001dea248Chris Lattner bool declspec, bool cxx0x) 1396a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), 1406a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc), 1416a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), 1426a34083e9f74a45e2f79c9fab66f177809a5db66Ted Kremenek Invalid(false), IsAvailability(true), UnavailableLoc(unavailable), 143fa5be3617294f0e3c341f0ecb6b2076478b1b5acTed Kremenek NextInPosition(0), NextInPool(0) { 144fa5be3617294f0e3c341f0ecb6b2076478b1b5acTed Kremenek new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); 145053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); 146053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); 147053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek AttrKind = getKind(getName()); 148053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek } 149053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek 150053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek friend class AttributePool; 151053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek friend class AttributeFactory; 152053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek 1538570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattnerpublic: 1548570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner enum Kind { // Please keep this list alphabetized. 1558570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_address_space, 1568570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_alias, 1578570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_aligned, 1588570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_always_inline, 1598570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_analyzer_noreturn, 1608570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_annotate, 1618570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_arc_weakref_unavailable, 1628570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_availability, // Clang-specific 1638570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_base_check, 1648570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_blocks, 1658570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_carries_dependency, 1668570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_cdecl, 1678570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_cf_consumed, // Clang-specific. 168053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek AT_cf_returns_autoreleased, // Clang-specific. 1698570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_cf_returns_not_retained, // Clang-specific. 1708570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_cf_returns_retained, // Clang-specific. 1718570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_cleanup, 1728570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_common, 173053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek AT_const, 174053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek AT_constant, 175053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek AT_constructor, 176053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek AT_deprecated, 177053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek AT_destructor, 178053ef593fa9d2b890645a914eee203231fb34458Ted Kremenek AT_device, 1798570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_dllexport, 1808570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_dllimport, 18157df3b950061c73d13d3116f747e79d7955a216aChris Lattner AT_ext_vector_type, 18257df3b950061c73d13d3116f747e79d7955a216aChris Lattner AT_fastcall, 18357df3b950061c73d13d3116f747e79d7955a216aChris Lattner AT_format, 18457df3b950061c73d13d3116f747e79d7955a216aChris Lattner AT_format_arg, 18557df3b950061c73d13d3116f747e79d7955a216aChris Lattner AT_global, 18657df3b950061c73d13d3116f747e79d7955a216aChris Lattner AT_gnu_inline, 18757df3b950061c73d13d3116f747e79d7955a216aChris Lattner AT_host, 18849cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_IBAction, // Clang-specific. 18957df3b950061c73d13d3116f747e79d7955a216aChris Lattner AT_IBOutlet, // Clang-specific. 1908570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_IBOutletCollection, // Clang-specific. 19157df3b950061c73d13d3116f747e79d7955a216aChris Lattner AT_init_priority, 1928570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_launch_bounds, 1938570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_malloc, 19449cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_may_alias, 195b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_mode, 196b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_MsStruct, 197b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_naked, 198b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_neon_polyvector_type, // Clang-specific. 199b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_neon_vector_type, // Clang-specific. 200b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_no_instrument_function, 201b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_nocommon, 202b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_nodebug, 2038570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_noinline, 204b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_nonnull, 205b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_noreturn, 206b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_nothrow, 207b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_ns_consumed, // Clang-specific. 208b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_ns_consumes_self, // Clang-specific. 209b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_ns_returns_autoreleased, // Clang-specific. 210b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_ns_returns_not_retained, // Clang-specific. 211b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_ns_returns_retained, // Clang-specific. 212b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_nsobject, 213b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_objc_exception, 214b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_objc_gc, 215b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_objc_method_family, 216b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_objc_ownership, // Clang-specific. 217b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_objc_precise_lifetime, // Clang-specific. 218b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_opencl_image_access, // OpenCL-specific. 219b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_opencl_kernel_function, // OpenCL-specific. 220b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_overloadable, // Clang-specific. 22149cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_ownership_holds, // Clang-specific. 22249cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_ownership_returns, // Clang-specific. 22349cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_ownership_takes, // Clang-specific. 22449cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_packed, 22549cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_pascal, 22649cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_pcs, // ARM specific 227b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_pure, 228b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_regparm, 22949cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_reqd_wg_size, 23049cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_section, 23149cd6354d5373245dd2e69ca7b7113e6a795d36eTed Kremenek AT_sentinel, 232b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_shared, 2338570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_stdcall, 234d6c1360c2bf234c73572a865f119d0518aca8154Ted Kremenek AT_thiscall, 235d6c1360c2bf234c73572a865f119d0518aca8154Ted Kremenek AT_transparent_union, 2368570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_unavailable, 2378570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_unused, 2388570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_used, 239d6c1360c2bf234c73572a865f119d0518aca8154Ted Kremenek AT_uuid, 2408570f0b0fde7ca812f8d37f52305f3df4dd2ce01Chris Lattner AT_vecreturn, // PS3 PPU-specific. 241b485cd1e0a5a1e942d0e682b9b1c4bc9df111528Ted Kremenek AT_vector_size, 242ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek AT_visibility, 243ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek AT_warn_unused_result, 244ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek AT_weak, 245ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek AT_weak_import, 246ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek AT_weakref, 247ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek IgnoredAttribute, 248ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek UnknownAttribute 249ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek }; 250ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek 251ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek IdentifierInfo *getName() const { return AttrName; } 252ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek SourceLocation getLoc() const { return AttrLoc; } 25370bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek 25407339a63b46e38c954fcccbef721c609d0c2040eTed Kremenek bool hasScope() const { return ScopeName; } 25507339a63b46e38c954fcccbef721c609d0c2040eTed Kremenek IdentifierInfo *getScopeName() const { return ScopeName; } 25607339a63b46e38c954fcccbef721c609d0c2040eTed Kremenek SourceLocation getScopeLoc() const { return ScopeLoc; } 25770bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek 25870bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek IdentifierInfo *getParameterName() const { return ParmName; } 25970bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek SourceLocation getParameterLoc() const { return ParmLoc; } 2604b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek 26170bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek bool isDeclspecAttribute() const { return DeclspecAttribute; } 26270bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek bool isCXX0XAttribute() const { return CXX0XAttribute; } 26370bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek 2645ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner bool isInvalid() const { return Invalid; } 265c4586c234edd8df0477a895aebcbc3eb220aed6bChris Lattner void setInvalid(bool b = true) const { Invalid = b; } 2665deb96d06583abb751463427457d46041af262d0Chris Lattner 2676f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner Kind getKind() const { return Kind(AttrKind); } 26807339a63b46e38c954fcccbef721c609d0c2040eTed Kremenek static Kind getKind(const IdentifierInfo *Name); 26907339a63b46e38c954fcccbef721c609d0c2040eTed Kremenek 27007339a63b46e38c954fcccbef721c609d0c2040eTed Kremenek AttributeList *getNext() const { return NextInPosition; } 2716f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner void setNext(AttributeList *N) { NextInPosition = N; } 2726f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner 2736f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner /// getNumArgs - Return the number of actual arguments to this attribute. 2746f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner unsigned getNumArgs() const { return NumArgs; } 2756f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner 27670bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek /// hasParameterOrArguments - Return true if this attribute has a parameter, 27770bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek /// or has a non empty argument expression list. 27870bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek bool hasParameterOrArguments() const { return ParmName || NumArgs; } 27970bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek 28070bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek /// getArg - Return the specified argument. 28170bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek Expr *getArg(unsigned Arg) const { 28270bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek assert(Arg < NumArgs && "Arg access out of range!"); 28370bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek return getArgsBuffer()[Arg]; 28470bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek } 28570bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek 28670bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek class arg_iterator { 28770bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek Expr * const *X; 28870bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek unsigned Idx; 28970bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek public: 29070bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek arg_iterator(Expr * const *x, unsigned idx) : X(x), Idx(idx) {} 29170bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek 2924b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek arg_iterator& operator++() { 2934b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek ++Idx; 2944b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek return *this; 2954b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek } 2964b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek 2974b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek bool operator==(const arg_iterator& I) const { 2984b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek assert (X == I.X && 2994b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek "compared arg_iterators are for different argument lists"); 3004b0f81323b518429203051bbcd4864bbf4b000a9Ted Kremenek return Idx == I.Idx; 30170bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek } 30270bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek 303ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek bool operator!=(const arg_iterator& I) const { 304ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek return !operator==(I); 30570bcba6030a76edf46c4f941ad9a5297a1f98c47Ted Kremenek } 306ad0a203130dc5d1fb7231b88767174511424fa98Ted Kremenek 3073245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner Expr* operator*() const { 3083245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner return X[Idx]; 3093245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner } 3103245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner 3113245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner unsigned getArgNum() const { 3123245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner return Idx+1; 3133245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner } 3143245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner }; 315a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner 316a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner arg_iterator arg_begin() const { 317a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner return arg_iterator(getArgsBuffer(), 0); 318a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner } 319a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner 320a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner arg_iterator arg_end() const { 321a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner return arg_iterator(getArgsBuffer(), NumArgs); 3223245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner } 3233245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner 324678c6358c8d4e368c78629099142397c63c1ee35Chris Lattner const AvailabilityChange &getAvailabilityIntroduced() const { 3253245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner assert(getKind() == AT_availability && "Not an availability attribute"); 326c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner return getAvailabilitySlot(IntroducedSlot); 327c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner } 3283245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner 329a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner const AvailabilityChange &getAvailabilityDeprecated() const { 33074ea3e5c57c087c046223096a97ea4e365f85eb6Chris Lattner assert(getKind() == AT_availability && "Not an availability attribute"); 33174ea3e5c57c087c046223096a97ea4e365f85eb6Chris Lattner return getAvailabilitySlot(DeprecatedSlot); 33274ea3e5c57c087c046223096a97ea4e365f85eb6Chris Lattner } 33374ea3e5c57c087c046223096a97ea4e365f85eb6Chris Lattner 33474ea3e5c57c087c046223096a97ea4e365f85eb6Chris Lattner const AvailabilityChange &getAvailabilityObsoleted() const { 3353245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner assert(getKind() == AT_availability && "Not an availability attribute"); 3363245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner return getAvailabilitySlot(ObsoletedSlot); 337a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner } 338a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner 339a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner SourceLocation getUnavailableLoc() const { 340a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner assert(getKind() == AT_availability && "Not an availability attribute"); 341a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner return UnavailableLoc; 342a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner } 343a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner}; 3445ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner 3455ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// A factory, from which one makes pools, from which one creates 3465ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattner/// individual attributes which are deallocated with the pool. 347c4586c234edd8df0477a895aebcbc3eb220aed6bChris Lattner/// 348a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner/// Note that it's tolerably cheap to create and destroy one of 3493245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner/// these as long as you don't actually allocate anything in it. 3505ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattnerclass AttributeFactory { 3515ef3e2c45f13fccdb0d7bbcf24c1beee8eee6f64Chris Lattnerpublic: 3523245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner enum { 3535deb96d06583abb751463427457d46041af262d0Chris Lattner /// The required allocation size of an availability attribute, 35474ea3e5c57c087c046223096a97ea4e365f85eb6Chris Lattner /// which we want to ensure is a multiple of sizeof(void*). 3555deb96d06583abb751463427457d46041af262d0Chris Lattner AvailabilityAllocSize = 3565deb96d06583abb751463427457d46041af262d0Chris Lattner sizeof(AttributeList) 3575deb96d06583abb751463427457d46041af262d0Chris Lattner + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1) 3585deb96d06583abb751463427457d46041af262d0Chris Lattner / sizeof(void*) * sizeof(void*)) 3595deb96d06583abb751463427457d46041af262d0Chris Lattner }; 3605deb96d06583abb751463427457d46041af262d0Chris Lattner 3615deb96d06583abb751463427457d46041af262d0Chris Lattnerprivate: 3625deb96d06583abb751463427457d46041af262d0Chris Lattner enum { 3635deb96d06583abb751463427457d46041af262d0Chris Lattner /// The number of free lists we want to be sure to support 3645deb96d06583abb751463427457d46041af262d0Chris Lattner /// inline. This is just enough that availability attributes 36574ea3e5c57c087c046223096a97ea4e365f85eb6Chris Lattner /// don't surpass it. It's actually very unlikely we'll see an 3665deb96d06583abb751463427457d46041af262d0Chris Lattner /// attribute that needs more than that; on x86-64 you'd need 10 3675deb96d06583abb751463427457d46041af262d0Chris Lattner /// expression arguments, and on i386 you'd need 19. 3685deb96d06583abb751463427457d46041af262d0Chris Lattner InlineFreeListsCapacity = 3695deb96d06583abb751463427457d46041af262d0Chris Lattner 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*) 3705deb96d06583abb751463427457d46041af262d0Chris Lattner }; 3715deb96d06583abb751463427457d46041af262d0Chris Lattner 3725deb96d06583abb751463427457d46041af262d0Chris Lattner llvm::BumpPtrAllocator Alloc; 3735deb96d06583abb751463427457d46041af262d0Chris Lattner 3743245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner /// Free lists. The index is determined by the following formula: 3753245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner /// (size - sizeof(AttributeList)) / sizeof(void*) 376a745e8c52839d9c8dd0fd8d5276b4eab182ec7f2Chris Lattner SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists; 37774ea3e5c57c087c046223096a97ea4e365f85eb6Chris Lattner 3783245a0a1c7a4fd74fca845b2edba275bb126d773Chris Lattner // The following are the private interface used by AttributePool. 379c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner friend class AttributePool; 380c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 381c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner /// Allocate an attribute of the given size. 382c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner void *allocate(size_t size); 383c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 384c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner /// Reclaim all the attributes in the given pool chain, which is 385c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner /// non-empty. Note that the current implementation is safe 386c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner /// against reclaiming things which were not actually allocated 387c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner /// with the allocator, although of course it's important to make 388c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner /// sure that their allocator lives at least as long as this one. 389c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner void reclaimPool(AttributeList *head); 390c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 391c54d50a4180520370c12dd7d06d035263d357d56Chris Lattnerpublic: 392c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner AttributeFactory(); 393c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner ~AttributeFactory(); 394c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner}; 395c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 396c54d50a4180520370c12dd7d06d035263d357d56Chris Lattnerclass AttributePool { 397c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner AttributeFactory &Factory; 398c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner AttributeList *Head; 399c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 400c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner void *allocate(size_t size) { 401c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner return Factory.allocate(size); 402c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner } 403c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 404c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner AttributeList *add(AttributeList *attr) { 405c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner // We don't care about the order of the pool. 406c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner attr->NextInPool = Head; 407c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner Head = attr; 408c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner return attr; 409c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner } 410c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 411c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner void takePool(AttributeList *pool); 412c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 413c54d50a4180520370c12dd7d06d035263d357d56Chris Lattnerpublic: 414c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner /// Create a new pool for a factory. 415c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner AttributePool(AttributeFactory &factory) : Factory(factory), Head(0) {} 416c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 417c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner /// Move the given pool's allocations to this pool. 418c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) { 419c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner pool.Head = 0; 420c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner } 421c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 422c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner AttributeFactory &getFactory() const { return Factory; } 4236f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner 424c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner void clear() { 425c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner if (Head) { 426c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner Factory.reclaimPool(Head); 427c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner Head = 0; 4286f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner } 4296f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner } 4306f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner 431c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner /// Take the given pool's allocations and add them to this pool. 432c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner void takeAllFrom(AttributePool &pool) { 433c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner if (pool.Head) { 434c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner takePool(pool.Head); 435c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner pool.Head = 0; 436c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner } 437c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner } 4386f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner 4396f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner ~AttributePool() { 4406f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner if (Head) Factory.reclaimPool(Head); 4416f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner } 4426f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner 4436f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc, 4446f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner IdentifierInfo *scopeName, SourceLocation scopeLoc, 4456f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner IdentifierInfo *parmName, SourceLocation parmLoc, 4466f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner Expr **args, unsigned numArgs, 4476f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner bool declspec = false, bool cxx0x = false) { 448c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner void *memory = allocate(sizeof(AttributeList) 4496f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner + numArgs * sizeof(Expr*)); 4506f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner return add(new (memory) AttributeList(attrName, attrLoc, 4516f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner scopeName, scopeLoc, 4526f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner parmName, parmLoc, 4536f46be279f4bc8fc24611f060258bcfbe1c175c4Chris Lattner args, numArgs, 454c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner declspec, cxx0x)); 455c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner } 456c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner 457c54d50a4180520370c12dd7d06d035263d357d56Chris Lattner AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc, 458 IdentifierInfo *scopeName, SourceLocation scopeLoc, 459 IdentifierInfo *parmName, SourceLocation parmLoc, 460 const AvailabilityChange &introduced, 461 const AvailabilityChange &deprecated, 462 const AvailabilityChange &obsoleted, 463 SourceLocation unavailable, 464 bool declspec = false, bool cxx0x = false) { 465 void *memory = allocate(AttributeFactory::AvailabilityAllocSize); 466 return add(new (memory) AttributeList(attrName, attrLoc, 467 scopeName, scopeLoc, 468 parmName, parmLoc, 469 introduced, deprecated, obsoleted, 470 unavailable, 471 declspec, cxx0x)); 472 } 473 474 AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name, 475 SourceLocation TokLoc, int Arg); 476}; 477 478/// addAttributeLists - Add two AttributeLists together 479/// The right-hand list is appended to the left-hand list, if any 480/// A pointer to the joined list is returned. 481/// Note: the lists are not left unmodified. 482inline AttributeList *addAttributeLists(AttributeList *Left, 483 AttributeList *Right) { 484 if (!Left) 485 return Right; 486 487 AttributeList *next = Left, *prev; 488 do { 489 prev = next; 490 next = next->getNext(); 491 } while (next); 492 prev->setNext(Right); 493 return Left; 494} 495 496/// CXX0XAttributeList - A wrapper around a C++0x attribute list. 497/// Stores, in addition to the list proper, whether or not an actual list was 498/// (as opposed to an empty list, which may be ill-formed in some places) and 499/// the source range of the list. 500struct CXX0XAttributeList { 501 AttributeList *AttrList; 502 SourceRange Range; 503 bool HasAttr; 504 CXX0XAttributeList (AttributeList *attrList, SourceRange range, bool hasAttr) 505 : AttrList(attrList), Range(range), HasAttr (hasAttr) { 506 } 507 CXX0XAttributeList () 508 : AttrList(0), Range(), HasAttr(false) { 509 } 510}; 511 512/// ParsedAttributes - A collection of parsed attributes. Currently 513/// we don't differentiate between the various attribute syntaxes, 514/// which is basically silly. 515/// 516/// Right now this is a very lightweight container, but the expectation 517/// is that this will become significantly more serious. 518class ParsedAttributes { 519public: 520 ParsedAttributes(AttributeFactory &factory) 521 : pool(factory), list(0) { 522 } 523 524 ParsedAttributes(ParsedAttributes &attrs) 525 : pool(attrs.pool), list(attrs.list) { 526 attrs.list = 0; 527 } 528 529 AttributePool &getPool() const { return pool; } 530 531 bool empty() const { return list == 0; } 532 533 void add(AttributeList *newAttr) { 534 assert(newAttr); 535 assert(newAttr->getNext() == 0); 536 newAttr->setNext(list); 537 list = newAttr; 538 } 539 540 void addAll(AttributeList *newList) { 541 if (!newList) return; 542 543 AttributeList *lastInNewList = newList; 544 while (AttributeList *next = lastInNewList->getNext()) 545 lastInNewList = next; 546 547 lastInNewList->setNext(list); 548 list = newList; 549 } 550 551 void set(AttributeList *newList) { 552 list = newList; 553 } 554 555 void takeAllFrom(ParsedAttributes &attrs) { 556 addAll(attrs.list); 557 attrs.list = 0; 558 pool.takeAllFrom(attrs.pool); 559 } 560 561 void clear() { list = 0; pool.clear(); } 562 AttributeList *getList() const { return list; } 563 564 /// Returns a reference to the attribute list. Try not to introduce 565 /// dependencies on this method, it may not be long-lived. 566 AttributeList *&getListRef() { return list; } 567 568 569 AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc, 570 IdentifierInfo *scopeName, SourceLocation scopeLoc, 571 IdentifierInfo *parmName, SourceLocation parmLoc, 572 Expr **args, unsigned numArgs, 573 bool declspec = false, bool cxx0x = false) { 574 AttributeList *attr = 575 pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc, 576 args, numArgs, declspec, cxx0x); 577 add(attr); 578 return attr; 579 } 580 581 AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc, 582 IdentifierInfo *scopeName, SourceLocation scopeLoc, 583 IdentifierInfo *parmName, SourceLocation parmLoc, 584 const AvailabilityChange &introduced, 585 const AvailabilityChange &deprecated, 586 const AvailabilityChange &obsoleted, 587 SourceLocation unavailable, 588 bool declspec = false, bool cxx0x = false) { 589 AttributeList *attr = 590 pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc, 591 introduced, deprecated, obsoleted, unavailable, 592 declspec, cxx0x); 593 add(attr); 594 return attr; 595 } 596 597 AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name, 598 SourceLocation loc, int arg) { 599 AttributeList *attr = 600 pool.createIntegerAttribute(C, name, loc, arg); 601 add(attr); 602 return attr; 603 } 604 605 606private: 607 mutable AttributePool pool; 608 AttributeList *list; 609}; 610 611} // end namespace clang 612 613#endif 614