From 36c49e3f258dced101949edabd72e9bc3f1dedc4 Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Fri, 17 Sep 2010 15:54:40 +0000
Subject: Vendor import of clang r114020 (from the release_28 branch):
 http://llvm.org/svn/llvm-project/cfe/branches/release_28@114020

Approved by:	rpaulo (mentor)
---
 include/clang/AST/Attr.h | 607 ++++++++++-------------------------------------
 1 file changed, 119 insertions(+), 488 deletions(-)

(limited to 'include/clang/AST/Attr.h')

diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 9faa62e..62ca49f 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -15,8 +15,11 @@
 #define LLVM_CLANG_AST_ATTR_H
 
 #include "llvm/Support/Casting.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "clang/Basic/AttrKinds.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
 #include <cassert>
 #include <cstring>
 #include <algorithm>
@@ -27,28 +30,39 @@ namespace clang {
   class IdentifierInfo;
   class ObjCInterfaceDecl;
   class Expr;
+  class QualType;
+  class FunctionDecl;
+  class TypeSourceInfo;
 }
 
 // Defined in ASTContext.h
 void *operator new(size_t Bytes, clang::ASTContext &C,
                    size_t Alignment = 16) throw ();
+// FIXME: Being forced to not have a default argument here due to redeclaration
+//        rules on default arguments sucks
+void *operator new[](size_t Bytes, clang::ASTContext &C,
+                     size_t Alignment) throw ();
 
 // It is good practice to pair new/delete operators.  Also, MSVC gives many
 // warnings if a matching delete overload is not declared, even though the
 // throw() spec guarantees it will not be implicitly called.
 void operator delete(void *Ptr, clang::ASTContext &C, size_t)
               throw ();
+void operator delete[](void *Ptr, clang::ASTContext &C, size_t)
+              throw ();
 
 namespace clang {
 
 /// Attr - This represents one attribute.
 class Attr {
 private:
-  Attr *Next;
-  attr::Kind AttrKind;
+  SourceLocation Loc;
+  unsigned AttrKind : 16;
   bool Inherited : 1;
 
 protected:
+  virtual ~Attr();
+  
   void* operator new(size_t bytes) throw() {
     assert(0 && "Attrs cannot be allocated with regular 'new'.");
     return 0;
@@ -57,41 +71,36 @@ protected:
     assert(0 && "Attrs cannot be released with regular 'delete'.");
   }
 
-protected:
-  Attr(attr::Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
-  virtual ~Attr() {
-    assert(Next == 0 && "Destroy didn't work");
+public:
+  // Forward so that the regular new and delete do not hide global ones.
+  void* operator new(size_t Bytes, ASTContext &C,
+                     size_t Alignment = 16) throw() {
+    return ::operator new(Bytes, C, Alignment);
   }
+  void operator delete(void *Ptr, ASTContext &C,
+                       size_t Alignment) throw() {
+    return ::operator delete(Ptr, C, Alignment);
+  }
+
+protected:
+  Attr(attr::Kind AK, SourceLocation L)
+    : Loc(L), AttrKind(AK), Inherited(false) {}
+
 public:
-  virtual void Destroy(ASTContext &C);
 
   /// \brief Whether this attribute should be merged to new
   /// declarations.
   virtual bool isMerged() const { return true; }
 
-  attr::Kind getKind() const { return AttrKind; }
-
-  Attr *getNext() { return Next; }
-  const Attr *getNext() const { return Next; }
-  void setNext(Attr *next) { Next = next; }
-
-  template<typename T> const T *getNext() const {
-    for (const Attr *attr = getNext(); attr; attr = attr->getNext())
-      if (const T *V = dyn_cast<T>(attr))
-        return V;
-    return 0;
+  attr::Kind getKind() const {
+    return static_cast<attr::Kind>(AttrKind);
   }
 
-  bool isInherited() const { return Inherited; }
-  void setInherited(bool value) { Inherited = value; }
-
-  void addAttr(Attr *attr) {
-    assert((attr != 0) && "addAttr(): attr is null");
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
 
-    // FIXME: This doesn't preserve the order in any way.
-    attr->Next = Next;
-    Next = attr;
-  }
+  bool isInherited() const { return Inherited; }
+  void setInherited(bool I) { Inherited = I; }
 
   // Clone this attribute.
   virtual Attr* clone(ASTContext &C) const = 0;
@@ -101,490 +110,112 @@ public:
 };
 
 #include "clang/AST/Attrs.inc"
-  
-class AttrWithString : public Attr {
-private:
-  const char *Str;
-  unsigned StrLen;
-protected:
-  AttrWithString(attr::Kind AK, ASTContext &C, llvm::StringRef s);
-  llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
-  void ReplaceString(ASTContext &C, llvm::StringRef newS);
-public:
-  virtual void Destroy(ASTContext &C);
-};
-
-#define DEF_SIMPLE_ATTR(ATTR)                                           \
-class ATTR##Attr : public Attr {                                        \
-public:                                                                 \
-  ATTR##Attr() : Attr(attr::ATTR) {}                                          \
-  virtual Attr *clone(ASTContext &C) const;                             \
-  static bool classof(const Attr *A) { return A->getKind() == attr::ATTR; }   \
-  static bool classof(const ATTR##Attr *A) { return true; }             \
-}
 
-DEF_SIMPLE_ATTR(Packed);
-
-/// \brief Attribute for specifying a maximum field alignment; this is only
-/// valid on record decls.
-class MaxFieldAlignmentAttr : public Attr {
-  unsigned Alignment;
-
-public:
-  MaxFieldAlignmentAttr(unsigned alignment)
-    : Attr(attr::MaxFieldAlignment), Alignment(alignment) {}
+/// AttrVec - A vector of Attr, which is how they are stored on the AST.
+typedef llvm::SmallVector<Attr*, 2> AttrVec;
+typedef llvm::SmallVector<const Attr*, 2> ConstAttrVec;
 
-  /// getAlignment - The specified alignment in bits.
-  unsigned getAlignment() const { return Alignment; }
-
-  virtual Attr* clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::MaxFieldAlignment;
-  }
-  static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AlignMac68k);
-
-/// \brief Atribute for specifying the alignment of a variable or type.
-///
-/// This node will either contain the precise Alignment (in bits, not bytes!)
-/// or will contain the expression for the alignment attribute in the case of
-/// a dependent expression within a class or function template. At template
-/// instantiation time these are transformed into concrete attributes.
-class AlignedAttr : public Attr {
-  unsigned Alignment;
-  Expr *AlignmentExpr;
-public:
-  AlignedAttr(unsigned alignment)
-    : Attr(attr::Aligned), Alignment(alignment), AlignmentExpr(0) {}
-  AlignedAttr(Expr *E)
-    : Attr(attr::Aligned), Alignment(0), AlignmentExpr(E) {}
-
-  /// getAlignmentExpr - Get a dependent alignment expression if one is present.
-  Expr *getAlignmentExpr() const {
-    return AlignmentExpr;
-  }
-
-  /// isDependent - Is the alignment a dependent expression
-  bool isDependent() const {
-    return getAlignmentExpr();
-  }
+/// DestroyAttrs - Destroy the contents of an AttrVec.
+inline void DestroyAttrs (AttrVec& V, ASTContext &C) {
+}
 
-  /// getAlignment - The specified alignment in bits. Requires !isDependent().
-  unsigned getAlignment() const {
-    assert(!isDependent() && "Cannot get a value dependent alignment");
-    return Alignment;
-  }
+/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
+/// providing attributes that are of a specifc type.
+template <typename SpecificAttr>
+class specific_attr_iterator {
+  /// Current - The current, underlying iterator.
+  /// In order to ensure we don't dereference an invalid iterator unless
+  /// specifically requested, we don't necessarily advance this all the
+  /// way. Instead, we advance it when an operation is requested; if the
+  /// operation is acting on what should be a past-the-end iterator,
+  /// then we offer no guarantees, but this way we do not dererence a
+  /// past-the-end iterator when we move to a past-the-end position.
+  mutable AttrVec::const_iterator Current;
 
-  /// getMaxAlignment - Get the maximum alignment of attributes on this list.
-  unsigned getMaxAlignment() const {
-    const AlignedAttr *Next = getNext<AlignedAttr>();
-    if (Next)
-      return std::max(Next->getMaxAlignment(), getAlignment());
-    else
-      return getAlignment();
+  void AdvanceToNext() const {
+    while (!llvm::isa<SpecificAttr>(*Current))
+      ++Current;
   }
 
-  virtual Attr* clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::Aligned;
+  void AdvanceToNext(AttrVec::const_iterator I) const {
+    while (Current != I && !llvm::isa<SpecificAttr>(*Current))
+      ++Current;
   }
-  static bool classof(const AlignedAttr *A) { return true; }
-};
 
-class AnnotateAttr : public AttrWithString {
 public:
-  AnnotateAttr(ASTContext &C, llvm::StringRef ann)
-    : AttrWithString(attr::Annotate, C, ann) {}
-
-  llvm::StringRef getAnnotation() const { return getString(); }
+  typedef SpecificAttr*             value_type;
+  typedef SpecificAttr*             reference;
+  typedef SpecificAttr*             pointer;
+  typedef std::forward_iterator_tag iterator_category;
+  typedef std::ptrdiff_t            difference_type;
 
-  virtual Attr* clone(ASTContext &C) const;
+  specific_attr_iterator() : Current() { }
+  explicit specific_attr_iterator(AttrVec::const_iterator i) : Current(i) { }
 
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::Annotate;
+  reference operator*() const {
+    AdvanceToNext();
+    return llvm::cast<SpecificAttr>(*Current);
   }
-  static bool classof(const AnnotateAttr *A) { return true; }
-};
-
-class AsmLabelAttr : public AttrWithString {
-public:
-  AsmLabelAttr(ASTContext &C, llvm::StringRef L)
-    : AttrWithString(attr::AsmLabel, C, L) {}
-
-  llvm::StringRef getLabel() const { return getString(); }
-
-  virtual Attr* clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::AsmLabel;
-  }
-  static bool classof(const AsmLabelAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AlwaysInline);
-
-class AliasAttr : public AttrWithString {
-public:
-  AliasAttr(ASTContext &C, llvm::StringRef aliasee)
-    : AttrWithString(attr::Alias, C, aliasee) {}
-
-  llvm::StringRef getAliasee() const { return getString(); }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Alias; }
-  static bool classof(const AliasAttr *A) { return true; }
-};
-
-class ConstructorAttr : public Attr {
-  int priority;
-public:
-  ConstructorAttr(int p) : Attr(attr::Constructor), priority(p) {}
-
-  int getPriority() const { return priority; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::Constructor; }
-  static bool classof(const ConstructorAttr *A) { return true; }
-};
-
-class DestructorAttr : public Attr {
-  int priority;
-public:
-  DestructorAttr(int p) : Attr(attr::Destructor), priority(p) {}
-
-  int getPriority() const { return priority; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::Destructor; }
-  static bool classof(const DestructorAttr *A) { return true; }
-};
-
-class IBOutletAttr : public Attr {
-public:
-  IBOutletAttr() : Attr(attr::IBOutlet) {}
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::IBOutlet;
-  }
-  static bool classof(const IBOutletAttr *A) { return true; }
-};
-
-class IBOutletCollectionAttr : public Attr {
-  const ObjCInterfaceDecl *D;
-public:
-  IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0)
-    : Attr(attr::IBOutletCollection), D(d) {}
-
-  const ObjCInterfaceDecl *getClass() const { return D; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::IBOutletCollection;
+  pointer operator->() const {
+    AdvanceToNext();
+    return llvm::cast<SpecificAttr>(*Current);
   }
-  static bool classof(const IBOutletCollectionAttr *A) { return true; }
-};
-
-class IBActionAttr : public Attr {
-public:
-  IBActionAttr() : Attr(attr::IBAction) {}
-
-  virtual Attr *clone(ASTContext &C) const;
 
-    // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::IBAction;
+  specific_attr_iterator& operator++() {
+    ++Current;
+    return *this;
   }
-  static bool classof(const IBActionAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AnalyzerNoReturn);
-DEF_SIMPLE_ATTR(Deprecated);
-DEF_SIMPLE_ATTR(GNUInline);
-DEF_SIMPLE_ATTR(Malloc);
-DEF_SIMPLE_ATTR(NoReturn);
-DEF_SIMPLE_ATTR(NoInstrumentFunction);
-
-class SectionAttr : public AttrWithString {
-public:
-  SectionAttr(ASTContext &C, llvm::StringRef N)
-    : AttrWithString(attr::Section, C, N) {}
-
-  llvm::StringRef getName() const { return getString(); }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::Section;
+  specific_attr_iterator operator++(int) {
+    specific_attr_iterator Tmp(*this);
+    ++(*this);
+    return Tmp;
   }
-  static bool classof(const SectionAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(Unavailable);
-DEF_SIMPLE_ATTR(Unused);
-DEF_SIMPLE_ATTR(Used);
-DEF_SIMPLE_ATTR(Weak);
-DEF_SIMPLE_ATTR(WeakImport);
-DEF_SIMPLE_ATTR(WeakRef);
-DEF_SIMPLE_ATTR(NoThrow);
-DEF_SIMPLE_ATTR(Const);
-DEF_SIMPLE_ATTR(Pure);
-
-class NonNullAttr : public Attr {
-  unsigned* ArgNums;
-  unsigned Size;
-public:
-  NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
-
-  virtual void Destroy(ASTContext &C);
-
-  typedef const unsigned *iterator;
-  iterator begin() const { return ArgNums; }
-  iterator end() const { return ArgNums + Size; }
-  unsigned size() const { return Size; }
 
-  bool isNonNull(unsigned arg) const {
-    return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
+  friend bool operator==(specific_attr_iterator Left,
+                         specific_attr_iterator Right) {
+    if (Left.Current < Right.Current)
+      Left.AdvanceToNext(Right.Current); 
+    else
+      Right.AdvanceToNext(Left.Current);
+    return Left.Current == Right.Current;
   }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  static bool classof(const Attr *A) { return A->getKind() == attr::NonNull; }
-  static bool classof(const NonNullAttr *A) { return true; }
-};
-
-class FormatAttr : public AttrWithString {
-  int formatIdx, firstArg;
-public:
-  FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
-    : AttrWithString(attr::Format, C, type), formatIdx(idx), firstArg(first) {}
-
-  llvm::StringRef getType() const { return getString(); }
-  void setType(ASTContext &C, llvm::StringRef type);
-  int getFormatIdx() const { return formatIdx; }
-  int getFirstArg() const { return firstArg; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Format; }
-  static bool classof(const FormatAttr *A) { return true; }
-};
-
-class FormatArgAttr : public Attr {
-  int formatIdx;
-public:
-  FormatArgAttr(int idx) : Attr(attr::FormatArg), formatIdx(idx) {}
-  int getFormatIdx() const { return formatIdx; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::FormatArg; }
-  static bool classof(const FormatArgAttr *A) { return true; }
-};
-
-class SentinelAttr : public Attr {
-  int sentinel, NullPos;
-public:
-  SentinelAttr(int sentinel_val, int nullPos) : Attr(attr::Sentinel),
-               sentinel(sentinel_val), NullPos(nullPos) {}
-  int getSentinel() const { return sentinel; }
-  int getNullPos() const { return NullPos; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Sentinel; }
-  static bool classof(const SentinelAttr *A) { return true; }
-};
-
-class VisibilityAttr : public Attr {
-public:
-  /// @brief An enumeration for the kinds of visibility of symbols.
-  enum VisibilityTypes {
-    DefaultVisibility = 0,
-    HiddenVisibility,
-    ProtectedVisibility
-  };
-private:
-  VisibilityTypes VisibilityType;
-public:
-  VisibilityAttr(VisibilityTypes v) : Attr(attr::Visibility),
-                 VisibilityType(v) {}
-
-  VisibilityTypes getVisibility() const { return VisibilityType; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::Visibility; }
-  static bool classof(const VisibilityAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(FastCall);
-DEF_SIMPLE_ATTR(StdCall);
-DEF_SIMPLE_ATTR(ThisCall);
-DEF_SIMPLE_ATTR(CDecl);
-DEF_SIMPLE_ATTR(TransparentUnion);
-DEF_SIMPLE_ATTR(ObjCNSObject);
-DEF_SIMPLE_ATTR(ObjCException);
-
-class OverloadableAttr : public Attr {
-public:
-  OverloadableAttr() : Attr(attr::Overloadable) { }
-
-  virtual bool isMerged() const { return false; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::Overloadable; }
-  static bool classof(const OverloadableAttr *) { return true; }
-};
-
-class BlocksAttr : public Attr {
-public:
-  enum BlocksAttrTypes {
-    ByRef = 0
-  };
-private:
-  BlocksAttrTypes BlocksAttrType;
-public:
-  BlocksAttr(BlocksAttrTypes t) : Attr(attr::Blocks), BlocksAttrType(t) {}
-
-  BlocksAttrTypes getType() const { return BlocksAttrType; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Blocks; }
-  static bool classof(const BlocksAttr *A) { return true; }
-};
-
-class FunctionDecl;
-
-class CleanupAttr : public Attr {
-  FunctionDecl *FD;
-
-public:
-  CleanupAttr(FunctionDecl *fd) : Attr(attr::Cleanup), FD(fd) {}
-
-  const FunctionDecl *getFunctionDecl() const { return FD; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Cleanup; }
-  static bool classof(const CleanupAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(NoDebug);
-DEF_SIMPLE_ATTR(WarnUnusedResult);
-DEF_SIMPLE_ATTR(NoInline);
-
-class RegparmAttr : public Attr {
-  unsigned NumParams;
-
-public:
-  RegparmAttr(unsigned np) : Attr(attr::Regparm), NumParams(np) {}
-
-  unsigned getNumParams() const { return NumParams; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Regparm; }
-  static bool classof(const RegparmAttr *A) { return true; }
-};
-
-class ReqdWorkGroupSizeAttr : public Attr {
-  unsigned X, Y, Z;
-public:
-  ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
-  : Attr(attr::ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
-
-  unsigned getXDim() const { return X; }
-  unsigned getYDim() const { return Y; }
-  unsigned getZDim() const { return Z; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::ReqdWorkGroupSize;
+  friend bool operator!=(specific_attr_iterator Left,
+                         specific_attr_iterator Right) {
+    return !(Left == Right);
   }
-  static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
 };
 
-class InitPriorityAttr : public Attr {
-  unsigned Priority;
-public:
-  InitPriorityAttr(unsigned priority) 
-    : Attr(attr::InitPriority),  Priority(priority) {}
-    
-  virtual void Destroy(ASTContext &C) { Attr::Destroy(C); }
-    
-  unsigned getPriority() const { return Priority; }
-    
-  virtual Attr *clone(ASTContext &C) const;
-    
-  static bool classof(const Attr *A) 
-    { return A->getKind() == attr::InitPriority; }
-  static bool classof(const InitPriorityAttr *A) { return true; }
-};
-  
-// Checker-specific attributes.
-DEF_SIMPLE_ATTR(CFReturnsNotRetained);
-DEF_SIMPLE_ATTR(CFReturnsRetained);
-DEF_SIMPLE_ATTR(NSReturnsNotRetained);
-DEF_SIMPLE_ATTR(NSReturnsRetained);
-
-// Target-specific attributes
-DEF_SIMPLE_ATTR(DLLImport);
-DEF_SIMPLE_ATTR(DLLExport);
-
-class MSP430InterruptAttr : public Attr {
-  unsigned Number;
-
-public:
-  MSP430InterruptAttr(unsigned n) : Attr(attr::MSP430Interrupt), Number(n) {}
-
-  unsigned getNumber() const { return Number; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::MSP430Interrupt; }
-  static bool classof(const MSP430InterruptAttr *A) { return true; }
-};
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_begin(const AttrVec& vec) {
+  return specific_attr_iterator<T>(vec.begin());
+}
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_end(const AttrVec& vec) {
+  return specific_attr_iterator<T>(vec.end());
+}
 
-DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
+template <typename T>
+inline bool hasSpecificAttr(const AttrVec& vec) {
+  return specific_attr_begin<T>(vec) != specific_attr_end<T>(vec);
+}
+template <typename T>
+inline T *getSpecificAttr(const AttrVec& vec) {
+  specific_attr_iterator<T> i = specific_attr_begin<T>(vec);
+  if (i != specific_attr_end<T>(vec))
+    return *i;
+  else
+    return 0;
+}
 
-#undef DEF_SIMPLE_ATTR
+/// getMaxAlignment - Returns the highest alignment value found among
+/// AlignedAttrs in an AttrVec, or 0 if there are none.
+inline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) {
+  unsigned Align = 0;
+  specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end());
+  for(; i != e; ++i)
+    Align = std::max(Align, i->getAlignment(Ctx));
+  return Align;
+}
 
 }  // end namespace clang
 
-- 
cgit v1.1