1801e60946bc879afeb37bcd3372e441e8f631c79James Dennett//===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===// 2d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson// 3d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson// The LLVM Compiler Infrastructure 4d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson// 5d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson// This file is distributed under the University of Illinois Open Source 6d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson// License. See LICENSE.TXT for details. 7d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson// 8d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson//===----------------------------------------------------------------------===// 9d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson// 10d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson// This file defines the Attr interface and subclasses. 11d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson// 12d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson//===----------------------------------------------------------------------===// 13d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson 1481226601148d7e7c187b96c6ef86e83df204f59fAnders Carlsson#ifndef LLVM_CLANG_AST_ATTR_H 1581226601148d7e7c187b96c6ef86e83df204f59fAnders Carlsson#define LLVM_CLANG_AST_ATTR_H 16d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson 179594675cc1eb52a054de13c4a21e466643847480Chris Lattner#include "clang/Basic/LLVM.h" 18387475d0c18aaeb022108de9d33b6c9fb7998843Sean Hunt#include "clang/Basic/AttrKinds.h" 19a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian#include "clang/AST/Type.h" 20cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt#include "clang/Basic/SourceLocation.h" 210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor#include "clang/Basic/VersionTuple.h" 229594675cc1eb52a054de13c4a21e466643847480Chris Lattner#include "llvm/ADT/SmallVector.h" 239594675cc1eb52a054de13c4a21e466643847480Chris Lattner#include "llvm/ADT/StringRef.h" 249594675cc1eb52a054de13c4a21e466643847480Chris Lattner#include "llvm/ADT/StringSwitch.h" 259fe8c74a93ac8e92512615c5f83e7a328b3b0544David Blaikie#include "llvm/Support/ErrorHandling.h" 261bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor#include "llvm/Support/raw_ostream.h" 27baa66fc389ca0a9f11e0c864304bcfd89de39439Anders Carlsson#include <cassert> 28ea7e97e14f2f1f9817d2ae8a25ec6ea652e5287fArgyrios Kyrtzidis#include <cstring> 29eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek#include <algorithm> 30adf21bdb3d17acfdb74657fcbc5035a404c6c8f4Anders Carlsson 31d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlssonnamespace clang { 32cc5814732edc0c382d0136ab57ec6149566043e2Chris Lattner class ASTContext; 33857e918a8a40deb128840308a318bf623d68295fTed Kremenek class IdentifierInfo; 34857e918a8a40deb128840308a318bf623d68295fTed Kremenek class ObjCInterfaceDecl; 354ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth class Expr; 36a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian class QualType; 37cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt class FunctionDecl; 38cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt class TypeSourceInfo; 399f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor} 409f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor 419509108b3dde280dca1999b5c054f5b789581e68Chris Lattner// Defined in ASTContext.h 424ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadvoid *operator new(size_t Bytes, const clang::ASTContext &C, 4329293cddc682091a16a71f513e605995473f7f45Dylan Noblesmith size_t Alignment = 16); 44cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt// FIXME: Being forced to not have a default argument here due to redeclaration 45cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt// rules on default arguments sucks 464ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadvoid *operator new[](size_t Bytes, const clang::ASTContext &C, 4729293cddc682091a16a71f513e605995473f7f45Dylan Noblesmith size_t Alignment); 489f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor 499509108b3dde280dca1999b5c054f5b789581e68Chris Lattner// It is good practice to pair new/delete operators. Also, MSVC gives many 509509108b3dde280dca1999b5c054f5b789581e68Chris Lattner// warnings if a matching delete overload is not declared, even though the 519509108b3dde280dca1999b5c054f5b789581e68Chris Lattner// throw() spec guarantees it will not be implicitly called. 5229293cddc682091a16a71f513e605995473f7f45Dylan Noblesmithvoid operator delete(void *Ptr, const clang::ASTContext &C, size_t); 5329293cddc682091a16a71f513e605995473f7f45Dylan Noblesmithvoid operator delete[](void *Ptr, const clang::ASTContext &C, size_t); 549509108b3dde280dca1999b5c054f5b789581e68Chris Lattner 559f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregornamespace clang { 56d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson 57d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson/// Attr - This represents one attribute. 58d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlssonclass Attr { 59d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlssonprivate: 60ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis SourceRange Range; 61cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt unsigned AttrKind : 16; 622f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 63d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlssonprotected: 64a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne bool Inherited : 1; 65a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne 661de22a26c0e126b08edb2eda9d9091c021d96dc6Douglas Gregor virtual ~Attr(); 671de22a26c0e126b08edb2eda9d9091c021d96dc6Douglas Gregor 680b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner void* operator new(size_t bytes) throw() { 69b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Attrs cannot be allocated with regular 'new'."); 700b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner } 710b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner void operator delete(void* data) throw() { 72b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Attrs cannot be released with regular 'delete'."); 730b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner } 741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 75cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntpublic: 76cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // Forward so that the regular new and delete do not hide global ones. 77cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt void* operator new(size_t Bytes, ASTContext &C, 78cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size_t Alignment = 16) throw() { 79cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return ::operator new(Bytes, C, Alignment); 80cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt } 81cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt void operator delete(void *Ptr, ASTContext &C, 82a87cdc03f4014545a8440110c1f4f68701100576Eli Friedman size_t Alignment) throw() { 83cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return ::operator delete(Ptr, C, Alignment); 84cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt } 85cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 860b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattnerprotected: 87ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Attr(attr::Kind AK, SourceRange R) 88ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis : Range(R), AttrKind(AK), Inherited(false) {} 89cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 90cc5814732edc0c382d0136ab57ec6149566043e2Chris Lattnerpublic: 911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 92cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt attr::Kind getKind() const { 93cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return static_cast<attr::Kind>(AttrKind); 94d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson } 951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 96ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis SourceLocation getLocation() const { return Range.getBegin(); } 97ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis SourceRange getRange() const { return Range; } 98ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis void setRange(SourceRange R) { Range = R; } 991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 100192e7f7e7f0493f7cdfda1d752e6de340d4e3ffePeter Collingbourne bool isInherited() const { return Inherited; } 101192e7f7e7f0493f7cdfda1d752e6de340d4e3ffePeter Collingbourne 1029f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor // Clone this attribute. 1039f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor virtual Attr* clone(ASTContext &C) const = 0; 1049f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor 10523323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins virtual bool isLateParsed() const { return false; } 10623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins 1071bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor // Pretty print this attribute. 1080dae729a69c4fccc38c97d5dd44f7b20bb20de1cRichard Smith virtual void printPretty(llvm::raw_ostream &OS, 1090dae729a69c4fccc38c97d5dd44f7b20bb20de1cRichard Smith const PrintingPolicy &Policy) const = 0; 1101bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor 111d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson // Implement isa/cast/dyncast/etc. 112d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson static bool classof(const Attr *) { return true; } 113d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson}; 114387475d0c18aaeb022108de9d33b6c9fb7998843Sean Hunt 115a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourneclass InheritableAttr : public Attr { 11699ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie virtual void anchor(); 117a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourneprotected: 118768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis InheritableAttr(attr::Kind AK, SourceRange R) 119768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis : Attr(AK, R) {} 120a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne 121a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbournepublic: 122a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne void setInherited(bool I) { Inherited = I; } 123a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne 124a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne // Implement isa/cast/dyncast/etc. 125a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne static bool classof(const Attr *A) { 126a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne return A->getKind() <= attr::LAST_INHERITABLE; 127a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne } 128a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne static bool classof(const InheritableAttr *) { return true; } 129a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne}; 130a97d70b7ea9633e8cbf976510d7a9ea66f4ac96cPeter Collingbourne 131eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCallclass InheritableParamAttr : public InheritableAttr { 13299ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie virtual void anchor(); 133eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCallprotected: 134768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis InheritableParamAttr(attr::Kind AK, SourceRange R) 135768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis : InheritableAttr(AK, R) {} 136eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCall 137eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCallpublic: 138eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCall // Implement isa/cast/dyncast/etc. 139eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCall static bool classof(const Attr *A) { 140eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCall return A->getKind() <= attr::LAST_INHERITABLE_PARAM; 141eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCall } 142eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCall static bool classof(const InheritableParamAttr *) { return true; } 143eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCall}; 144eca5d22c16eb784e5f35ca816fa22e0c0e060417John McCall 145387475d0c18aaeb022108de9d33b6c9fb7998843Sean Hunt#include "clang/AST/Attrs.inc" 1461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 147cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// AttrVec - A vector of Attr, which is how they are stored on the AST. 148686775deca8b8685eb90801495880e3abdd844c2Chris Lattnertypedef SmallVector<Attr*, 2> AttrVec; 149686775deca8b8685eb90801495880e3abdd844c2Chris Lattnertypedef SmallVector<const Attr*, 2> ConstAttrVec; 150dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 151cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only 152cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// providing attributes that are of a specifc type. 1534990890fc9428f98bef90ba349203a648c592778Alexander Kornienkotemplate <typename SpecificAttr, typename Container = AttrVec> 154cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntclass specific_attr_iterator { 1554990890fc9428f98bef90ba349203a648c592778Alexander Kornienko typedef typename Container::const_iterator Iterator; 1564990890fc9428f98bef90ba349203a648c592778Alexander Kornienko 157cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// Current - The current, underlying iterator. 158cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// In order to ensure we don't dereference an invalid iterator unless 159cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// specifically requested, we don't necessarily advance this all the 160cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// way. Instead, we advance it when an operation is requested; if the 161cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// operation is acting on what should be a past-the-end iterator, 162cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// then we offer no guarantees, but this way we do not dererence a 163cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// past-the-end iterator when we move to a past-the-end position. 1644990890fc9428f98bef90ba349203a648c592778Alexander Kornienko mutable Iterator Current; 165dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 166cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt void AdvanceToNext() const { 1679594675cc1eb52a054de13c4a21e466643847480Chris Lattner while (!isa<SpecificAttr>(*Current)) 168cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ++Current; 169dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 170dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1714990890fc9428f98bef90ba349203a648c592778Alexander Kornienko void AdvanceToNext(Iterator I) const { 1729594675cc1eb52a054de13c4a21e466643847480Chris Lattner while (Current != I && !isa<SpecificAttr>(*Current)) 173cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ++Current; 174dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 175dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 176dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekpublic: 177cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef SpecificAttr* value_type; 178cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef SpecificAttr* reference; 179cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef SpecificAttr* pointer; 180cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef std::forward_iterator_tag iterator_category; 181cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef std::ptrdiff_t difference_type; 182dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 183cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator() : Current() { } 1844990890fc9428f98bef90ba349203a648c592778Alexander Kornienko explicit specific_attr_iterator(Iterator i) : Current(i) { } 185dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 186cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt reference operator*() const { 187cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt AdvanceToNext(); 1889594675cc1eb52a054de13c4a21e466643847480Chris Lattner return cast<SpecificAttr>(*Current); 189dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 190cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt pointer operator->() const { 191cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt AdvanceToNext(); 1929594675cc1eb52a054de13c4a21e466643847480Chris Lattner return cast<SpecificAttr>(*Current); 193dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 194dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 195cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator& operator++() { 196cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ++Current; 197cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return *this; 198dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 199cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator operator++(int) { 200cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator Tmp(*this); 201cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ++(*this); 202cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return Tmp; 203dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 204dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 205cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt friend bool operator==(specific_attr_iterator Left, 206cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator Right) { 207cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (Left.Current < Right.Current) 208cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Left.AdvanceToNext(Right.Current); 209cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt else 210cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Right.AdvanceToNext(Left.Current); 211cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return Left.Current == Right.Current; 212dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 213cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt friend bool operator!=(specific_attr_iterator Left, 214cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator Right) { 215cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return !(Left == Right); 216dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 217dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}; 218dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 2194990890fc9428f98bef90ba349203a648c592778Alexander Kornienkotemplate <typename SpecificAttr, typename Container> 2204990890fc9428f98bef90ba349203a648c592778Alexander Kornienkoinline specific_attr_iterator<SpecificAttr, Container> 2214990890fc9428f98bef90ba349203a648c592778Alexander Kornienko specific_attr_begin(const Container& container) { 2224990890fc9428f98bef90ba349203a648c592778Alexander Kornienko return specific_attr_iterator<SpecificAttr, Container>(container.begin()); 223cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2244990890fc9428f98bef90ba349203a648c592778Alexander Kornienkotemplate <typename SpecificAttr, typename Container> 2254990890fc9428f98bef90ba349203a648c592778Alexander Kornienkoinline specific_attr_iterator<SpecificAttr, Container> 2264990890fc9428f98bef90ba349203a648c592778Alexander Kornienko specific_attr_end(const Container& container) { 2274990890fc9428f98bef90ba349203a648c592778Alexander Kornienko return specific_attr_iterator<SpecificAttr, Container>(container.end()); 228cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 22982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 2304990890fc9428f98bef90ba349203a648c592778Alexander Kornienkotemplate <typename SpecificAttr, typename Container> 2314990890fc9428f98bef90ba349203a648c592778Alexander Kornienkoinline bool hasSpecificAttr(const Container& container) { 2324990890fc9428f98bef90ba349203a648c592778Alexander Kornienko return specific_attr_begin<SpecificAttr>(container) != 2334990890fc9428f98bef90ba349203a648c592778Alexander Kornienko specific_attr_end<SpecificAttr>(container); 234cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2354990890fc9428f98bef90ba349203a648c592778Alexander Kornienkotemplate <typename SpecificAttr, typename Container> 2364990890fc9428f98bef90ba349203a648c592778Alexander Kornienkoinline SpecificAttr *getSpecificAttr(const Container& container) { 2374990890fc9428f98bef90ba349203a648c592778Alexander Kornienko specific_attr_iterator<SpecificAttr, Container> i = 2384990890fc9428f98bef90ba349203a648c592778Alexander Kornienko specific_attr_begin<SpecificAttr>(container); 2394990890fc9428f98bef90ba349203a648c592778Alexander Kornienko if (i != specific_attr_end<SpecificAttr>(container)) 240cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return *i; 241cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt else 242cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return 0; 243cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2445a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 245cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// getMaxAlignment - Returns the highest alignment value found among 246cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// AlignedAttrs in an AttrVec, or 0 if there are none. 247cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntinline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) { 248cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt unsigned Align = 0; 249cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end()); 250cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for(; i != e; ++i) 251cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Align = std::max(Align, i->getAlignment(Ctx)); 252cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return Align; 253cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 255d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson} // end namespace clang 256d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson 257d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson#endif 258