Attr.h revision ffcc3105d223899740e79f3f8199f3881df4d1de
1//===--- Attr.h - Classes for representing expressions ----------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the Attr interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_ATTR_H
15#define LLVM_CLANG_AST_ATTR_H
16
17#include "clang/Basic/LLVM.h"
18#include "clang/Basic/AttrKinds.h"
19#include "clang/AST/Type.h"
20#include "clang/Basic/SourceLocation.h"
21#include "clang/Basic/VersionTuple.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/ADT/StringSwitch.h"
25#include <cassert>
26#include <cstring>
27#include <algorithm>
28
29namespace clang {
30  class ASTContext;
31  class IdentifierInfo;
32  class ObjCInterfaceDecl;
33  class Expr;
34  class QualType;
35  class FunctionDecl;
36  class TypeSourceInfo;
37}
38
39// Defined in ASTContext.h
40void *operator new(size_t Bytes, const clang::ASTContext &C,
41                   size_t Alignment = 16) throw ();
42// FIXME: Being forced to not have a default argument here due to redeclaration
43//        rules on default arguments sucks
44void *operator new[](size_t Bytes, const clang::ASTContext &C,
45                     size_t Alignment) throw ();
46
47// It is good practice to pair new/delete operators.  Also, MSVC gives many
48// warnings if a matching delete overload is not declared, even though the
49// throw() spec guarantees it will not be implicitly called.
50void operator delete(void *Ptr, const clang::ASTContext &C, size_t)
51              throw ();
52void operator delete[](void *Ptr, const clang::ASTContext &C, size_t)
53              throw ();
54
55namespace clang {
56
57/// Attr - This represents one attribute.
58class Attr {
59private:
60  SourceRange Range;
61  unsigned AttrKind : 16;
62
63protected:
64  bool Inherited : 1;
65
66  virtual ~Attr();
67
68  void* operator new(size_t bytes) throw() {
69    assert(0 && "Attrs cannot be allocated with regular 'new'.");
70    return 0;
71  }
72  void operator delete(void* data) throw() {
73    assert(0 && "Attrs cannot be released with regular 'delete'.");
74  }
75
76public:
77  // Forward so that the regular new and delete do not hide global ones.
78  void* operator new(size_t Bytes, ASTContext &C,
79                     size_t Alignment = 16) throw() {
80    return ::operator new(Bytes, C, Alignment);
81  }
82  void operator delete(void *Ptr, ASTContext &C,
83                       size_t Alignment) throw() {
84    return ::operator delete(Ptr, C, Alignment);
85  }
86
87protected:
88  Attr(attr::Kind AK, SourceRange R)
89    : Range(R), AttrKind(AK), Inherited(false) {}
90
91public:
92
93  attr::Kind getKind() const {
94    return static_cast<attr::Kind>(AttrKind);
95  }
96
97  SourceLocation getLocation() const { return Range.getBegin(); }
98  SourceRange getRange() const { return Range; }
99  void setRange(SourceRange R) { Range = R; }
100
101  bool isInherited() const { return Inherited; }
102
103  // Clone this attribute.
104  virtual Attr* clone(ASTContext &C) const = 0;
105
106  // Implement isa/cast/dyncast/etc.
107  static bool classof(const Attr *) { return true; }
108};
109
110class InheritableAttr : public Attr {
111protected:
112  InheritableAttr(attr::Kind AK, SourceLocation L)
113    : Attr(AK, L) {}
114
115public:
116  void setInherited(bool I) { Inherited = I; }
117
118  // Implement isa/cast/dyncast/etc.
119  static bool classof(const Attr *A) {
120    return A->getKind() <= attr::LAST_INHERITABLE;
121  }
122  static bool classof(const InheritableAttr *) { return true; }
123};
124
125class InheritableParamAttr : public InheritableAttr {
126protected:
127  InheritableParamAttr(attr::Kind AK, SourceLocation L)
128    : InheritableAttr(AK, L) {}
129
130public:
131  // Implement isa/cast/dyncast/etc.
132  static bool classof(const Attr *A) {
133    return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
134  }
135  static bool classof(const InheritableParamAttr *) { return true; }
136};
137
138#include "clang/AST/Attrs.inc"
139
140/// AttrVec - A vector of Attr, which is how they are stored on the AST.
141typedef SmallVector<Attr*, 2> AttrVec;
142typedef SmallVector<const Attr*, 2> ConstAttrVec;
143
144/// DestroyAttrs - Destroy the contents of an AttrVec.
145inline void DestroyAttrs (AttrVec& V, ASTContext &C) {
146}
147
148/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
149/// providing attributes that are of a specifc type.
150template <typename SpecificAttr>
151class specific_attr_iterator {
152  /// Current - The current, underlying iterator.
153  /// In order to ensure we don't dereference an invalid iterator unless
154  /// specifically requested, we don't necessarily advance this all the
155  /// way. Instead, we advance it when an operation is requested; if the
156  /// operation is acting on what should be a past-the-end iterator,
157  /// then we offer no guarantees, but this way we do not dererence a
158  /// past-the-end iterator when we move to a past-the-end position.
159  mutable AttrVec::const_iterator Current;
160
161  void AdvanceToNext() const {
162    while (!isa<SpecificAttr>(*Current))
163      ++Current;
164  }
165
166  void AdvanceToNext(AttrVec::const_iterator I) const {
167    while (Current != I && !isa<SpecificAttr>(*Current))
168      ++Current;
169  }
170
171public:
172  typedef SpecificAttr*             value_type;
173  typedef SpecificAttr*             reference;
174  typedef SpecificAttr*             pointer;
175  typedef std::forward_iterator_tag iterator_category;
176  typedef std::ptrdiff_t            difference_type;
177
178  specific_attr_iterator() : Current() { }
179  explicit specific_attr_iterator(AttrVec::const_iterator i) : Current(i) { }
180
181  reference operator*() const {
182    AdvanceToNext();
183    return cast<SpecificAttr>(*Current);
184  }
185  pointer operator->() const {
186    AdvanceToNext();
187    return cast<SpecificAttr>(*Current);
188  }
189
190  specific_attr_iterator& operator++() {
191    ++Current;
192    return *this;
193  }
194  specific_attr_iterator operator++(int) {
195    specific_attr_iterator Tmp(*this);
196    ++(*this);
197    return Tmp;
198  }
199
200  friend bool operator==(specific_attr_iterator Left,
201                         specific_attr_iterator Right) {
202    if (Left.Current < Right.Current)
203      Left.AdvanceToNext(Right.Current);
204    else
205      Right.AdvanceToNext(Left.Current);
206    return Left.Current == Right.Current;
207  }
208  friend bool operator!=(specific_attr_iterator Left,
209                         specific_attr_iterator Right) {
210    return !(Left == Right);
211  }
212};
213
214template <typename T>
215inline specific_attr_iterator<T> specific_attr_begin(const AttrVec& vec) {
216  return specific_attr_iterator<T>(vec.begin());
217}
218template <typename T>
219inline specific_attr_iterator<T> specific_attr_end(const AttrVec& vec) {
220  return specific_attr_iterator<T>(vec.end());
221}
222
223template <typename T>
224inline bool hasSpecificAttr(const AttrVec& vec) {
225  return specific_attr_begin<T>(vec) != specific_attr_end<T>(vec);
226}
227template <typename T>
228inline T *getSpecificAttr(const AttrVec& vec) {
229  specific_attr_iterator<T> i = specific_attr_begin<T>(vec);
230  if (i != specific_attr_end<T>(vec))
231    return *i;
232  else
233    return 0;
234}
235
236/// getMaxAlignment - Returns the highest alignment value found among
237/// AlignedAttrs in an AttrVec, or 0 if there are none.
238inline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) {
239  unsigned Align = 0;
240  specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end());
241  for(; i != e; ++i)
242    Align = std::max(Align, i->getAlignment(Ctx));
243  return Align;
244}
245
246}  // end namespace clang
247
248#endif
249