Attr.h revision a87cdc03f4014545a8440110c1f4f68701100576
1d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson//===--- Attr.h - Classes for representing expressions ----------*- 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 17d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson#include "llvm/Support/Casting.h" 18cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt#include "llvm/ADT/SmallVector.h" 19bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer#include "llvm/ADT/StringRef.h" 20387475d0c18aaeb022108de9d33b6c9fb7998843Sean Hunt#include "clang/Basic/AttrKinds.h" 21a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian#include "clang/AST/Type.h" 22cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt#include "clang/Basic/SourceLocation.h" 23baa66fc389ca0a9f11e0c864304bcfd89de39439Anders Carlsson#include <cassert> 24ea7e97e14f2f1f9817d2ae8a25ec6ea652e5287fArgyrios Kyrtzidis#include <cstring> 25eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek#include <algorithm> 26bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramerusing llvm::dyn_cast; 27adf21bdb3d17acfdb74657fcbc5035a404c6c8f4Anders Carlsson 28d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlssonnamespace clang { 29cc5814732edc0c382d0136ab57ec6149566043e2Chris Lattner class ASTContext; 30857e918a8a40deb128840308a318bf623d68295fTed Kremenek class IdentifierInfo; 31857e918a8a40deb128840308a318bf623d68295fTed Kremenek class ObjCInterfaceDecl; 324ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth class Expr; 33a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian class QualType; 34cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt class FunctionDecl; 35cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt class TypeSourceInfo; 369f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor} 379f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor 389509108b3dde280dca1999b5c054f5b789581e68Chris Lattner// Defined in ASTContext.h 399f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregorvoid *operator new(size_t Bytes, clang::ASTContext &C, 409f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor size_t Alignment = 16) throw (); 41cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt// FIXME: Being forced to not have a default argument here due to redeclaration 42cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt// rules on default arguments sucks 43cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid *operator new[](size_t Bytes, clang::ASTContext &C, 44cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size_t Alignment) throw (); 459f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor 469509108b3dde280dca1999b5c054f5b789581e68Chris Lattner// It is good practice to pair new/delete operators. Also, MSVC gives many 479509108b3dde280dca1999b5c054f5b789581e68Chris Lattner// warnings if a matching delete overload is not declared, even though the 489509108b3dde280dca1999b5c054f5b789581e68Chris Lattner// throw() spec guarantees it will not be implicitly called. 499509108b3dde280dca1999b5c054f5b789581e68Chris Lattnervoid operator delete(void *Ptr, clang::ASTContext &C, size_t) 509509108b3dde280dca1999b5c054f5b789581e68Chris Lattner throw (); 51cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid operator delete[](void *Ptr, clang::ASTContext &C, size_t) 52cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt throw (); 539509108b3dde280dca1999b5c054f5b789581e68Chris Lattner 549f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregornamespace clang { 55d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson 56d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson/// Attr - This represents one attribute. 57d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlssonclass Attr { 58d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlssonprivate: 59cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt SourceLocation Loc; 60cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt unsigned AttrKind : 16; 612f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov bool Inherited : 1; 622f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 63d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlssonprotected: 641de22a26c0e126b08edb2eda9d9091c021d96dc6Douglas Gregor virtual ~Attr(); 651de22a26c0e126b08edb2eda9d9091c021d96dc6Douglas Gregor 660b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner void* operator new(size_t bytes) throw() { 670b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner assert(0 && "Attrs cannot be allocated with regular 'new'."); 680b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner return 0; 690b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner } 700b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner void operator delete(void* data) throw() { 710b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner assert(0 && "Attrs cannot be released with regular 'delete'."); 720b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner } 731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 74cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntpublic: 75cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // Forward so that the regular new and delete do not hide global ones. 76cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt void* operator new(size_t Bytes, ASTContext &C, 77cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size_t Alignment = 16) throw() { 78cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return ::operator new(Bytes, C, Alignment); 79cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt } 80cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt void operator delete(void *Ptr, ASTContext &C, 81a87cdc03f4014545a8440110c1f4f68701100576Eli Friedman size_t Alignment) throw() { 82cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return ::operator delete(Ptr, C, Alignment); 83cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt } 84cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 850b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattnerprotected: 86cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Attr(attr::Kind AK, SourceLocation L) 871bf8d6f3a9dc636c3d1217d6fff11acf358e44beSean Hunt : Loc(L), AttrKind(AK), Inherited(false) {} 88cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 89cc5814732edc0c382d0136ab57ec6149566043e2Chris Lattnerpublic: 901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 91ae17094c001972a5949944a0a77ef6adf2a92c8fDouglas Gregor /// \brief Whether this attribute should be merged to new 92ae17094c001972a5949944a0a77ef6adf2a92c8fDouglas Gregor /// declarations. 93ae17094c001972a5949944a0a77ef6adf2a92c8fDouglas Gregor virtual bool isMerged() const { return true; } 94ae17094c001972a5949944a0a77ef6adf2a92c8fDouglas Gregor 95cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt attr::Kind getKind() const { 96cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return static_cast<attr::Kind>(AttrKind); 97d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson } 981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 99cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt SourceLocation getLocation() const { return Loc; } 100cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt void setLocation(SourceLocation L) { Loc = L; } 1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 102cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt bool isInherited() const { return Inherited; } 103cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt void setInherited(bool I) { Inherited = I; } 1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1059f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor // Clone this attribute. 1069f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor virtual Attr* clone(ASTContext &C) const = 0; 1079f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor 108d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson // Implement isa/cast/dyncast/etc. 109d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson static bool classof(const Attr *) { return true; } 110d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson}; 111387475d0c18aaeb022108de9d33b6c9fb7998843Sean Hunt 112387475d0c18aaeb022108de9d33b6c9fb7998843Sean Hunt#include "clang/AST/Attrs.inc" 1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 114cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// AttrVec - A vector of Attr, which is how they are stored on the AST. 115cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunttypedef llvm::SmallVector<Attr*, 2> AttrVec; 116cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunttypedef llvm::SmallVector<const Attr*, 2> ConstAttrVec; 117dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 118cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// DestroyAttrs - Destroy the contents of an AttrVec. 119cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntinline void DestroyAttrs (AttrVec& V, ASTContext &C) { 120cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 121dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 122cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only 123cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// providing attributes that are of a specifc type. 124cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunttemplate <typename SpecificAttr> 125cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntclass specific_attr_iterator { 126cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// Current - The current, underlying iterator. 127cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// In order to ensure we don't dereference an invalid iterator unless 128cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// specifically requested, we don't necessarily advance this all the 129cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// way. Instead, we advance it when an operation is requested; if the 130cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// operation is acting on what should be a past-the-end iterator, 131cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// then we offer no guarantees, but this way we do not dererence a 132cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt /// past-the-end iterator when we move to a past-the-end position. 133cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt mutable AttrVec::const_iterator Current; 134dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 135cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt void AdvanceToNext() const { 136cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt while (!llvm::isa<SpecificAttr>(*Current)) 137cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ++Current; 138dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 139dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 140cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt void AdvanceToNext(AttrVec::const_iterator I) const { 141cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt while (Current != I && !llvm::isa<SpecificAttr>(*Current)) 142cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ++Current; 143dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 144dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 145dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekpublic: 146cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef SpecificAttr* value_type; 147cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef SpecificAttr* reference; 148cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef SpecificAttr* pointer; 149cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef std::forward_iterator_tag iterator_category; 150cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt typedef std::ptrdiff_t difference_type; 151dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 152cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator() : Current() { } 153cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt explicit specific_attr_iterator(AttrVec::const_iterator i) : Current(i) { } 154dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 155cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt reference operator*() const { 156cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt AdvanceToNext(); 157cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return llvm::cast<SpecificAttr>(*Current); 158dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 159cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt pointer operator->() const { 160cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt AdvanceToNext(); 161cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return llvm::cast<SpecificAttr>(*Current); 162dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 163dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 164cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator& operator++() { 165cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ++Current; 166cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return *this; 167dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 168cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator operator++(int) { 169cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator Tmp(*this); 170cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ++(*this); 171cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return Tmp; 172dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 173dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 174cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt friend bool operator==(specific_attr_iterator Left, 175cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator Right) { 176cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (Left.Current < Right.Current) 177cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Left.AdvanceToNext(Right.Current); 178cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt else 179cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Right.AdvanceToNext(Left.Current); 180cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return Left.Current == Right.Current; 181dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 182cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt friend bool operator!=(specific_attr_iterator Left, 183cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator Right) { 184cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return !(Left == Right); 185dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 186dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek}; 187dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 188cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunttemplate <typename T> 189cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntinline specific_attr_iterator<T> specific_attr_begin(const AttrVec& vec) { 190cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return specific_attr_iterator<T>(vec.begin()); 191cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 192cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunttemplate <typename T> 193cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntinline specific_attr_iterator<T> specific_attr_end(const AttrVec& vec) { 194cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return specific_attr_iterator<T>(vec.end()); 195cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 19682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov 197cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunttemplate <typename T> 198cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntinline bool hasSpecificAttr(const AttrVec& vec) { 199cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return specific_attr_begin<T>(vec) != specific_attr_end<T>(vec); 200cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 201cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunttemplate <typename T> 202cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntinline T *getSpecificAttr(const AttrVec& vec) { 203cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator<T> i = specific_attr_begin<T>(vec); 204cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (i != specific_attr_end<T>(vec)) 205cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return *i; 206cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt else 207cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return 0; 208cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2095a0164d6ab843ca61437ec59a504365cb1c98f43Charles Davis 210cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// getMaxAlignment - Returns the highest alignment value found among 211cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt/// AlignedAttrs in an AttrVec, or 0 if there are none. 212cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntinline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) { 213cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt unsigned Align = 0; 214cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end()); 215cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for(; i != e; ++i) 216cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Align = std::max(Align, i->getAlignment(Ctx)); 217cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return Align; 218cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 220d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson} // end namespace clang 221d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson 222d429cd459aef723fa0e7a44ac957d4c2256e241cAnders Carlsson#endif 223