clang  20.0.0git
AttrIterator.h
Go to the documentation of this file.
1 //===- AttrIterator.h - Classes for attribute iteration ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the Attr vector and specific_attr_iterator interfaces.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_AST_ATTRITERATOR_H
14 #define LLVM_CLANG_AST_ATTRITERATOR_H
15 
16 #include "clang/Basic/LLVM.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/Support/Casting.h"
19 #include <cassert>
20 #include <cstddef>
21 #include <iterator>
22 
23 namespace clang {
24 
25 class Attr;
26 
27 /// AttrVec - A vector of Attr, which is how they are stored on the AST.
29 
30 /// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
31 /// providing attributes that are of a specific type.
32 template <typename SpecificAttr, typename Container = AttrVec>
34  using Iterator = typename Container::const_iterator;
35 
36  /// Current - The current, underlying iterator.
37  /// In order to ensure we don't dereference an invalid iterator unless
38  /// specifically requested, we don't necessarily advance this all the
39  /// way. Instead, we advance it when an operation is requested; if the
40  /// operation is acting on what should be a past-the-end iterator,
41  /// then we offer no guarantees, but this way we do not dereference a
42  /// past-the-end iterator when we move to a past-the-end position.
43  mutable Iterator Current;
44 
45  void AdvanceToNext() const {
46  while (!isa<SpecificAttr>(*Current))
47  ++Current;
48  }
49 
50  void AdvanceToNext(Iterator I) const {
51  while (Current != I && !isa<SpecificAttr>(*Current))
52  ++Current;
53  }
54 
55 public:
56  using value_type = SpecificAttr *;
57  using reference = SpecificAttr *;
58  using pointer = SpecificAttr *;
59  using iterator_category = std::forward_iterator_tag;
61 
63  explicit specific_attr_iterator(Iterator i) : Current(i) {}
64 
65  reference operator*() const {
66  AdvanceToNext();
67  return cast<SpecificAttr>(*Current);
68  }
69  pointer operator->() const {
70  AdvanceToNext();
71  return cast<SpecificAttr>(*Current);
72  }
73 
75  ++Current;
76  return *this;
77  }
79  specific_attr_iterator Tmp(*this);
80  ++(*this);
81  return Tmp;
82  }
83 
85  specific_attr_iterator Right) {
86  assert((Left.Current == nullptr) == (Right.Current == nullptr));
87  if (Left.Current < Right.Current)
88  Left.AdvanceToNext(Right.Current);
89  else
90  Right.AdvanceToNext(Left.Current);
91  return Left.Current == Right.Current;
92  }
94  specific_attr_iterator Right) {
95  return !(Left == Right);
96  }
97 };
98 
99 template <typename SpecificAttr, typename Container>
100 inline specific_attr_iterator<SpecificAttr, Container>
101  specific_attr_begin(const Container& container) {
102  return specific_attr_iterator<SpecificAttr, Container>(container.begin());
103 }
104 template <typename SpecificAttr, typename Container>
105 inline specific_attr_iterator<SpecificAttr, Container>
106  specific_attr_end(const Container& container) {
107  return specific_attr_iterator<SpecificAttr, Container>(container.end());
108 }
109 
110 template <typename SpecificAttr, typename Container>
111 inline bool hasSpecificAttr(const Container& container) {
112  return specific_attr_begin<SpecificAttr>(container) !=
113  specific_attr_end<SpecificAttr>(container);
114 }
115 template <typename SpecificAttr, typename Container>
116 inline SpecificAttr *getSpecificAttr(const Container& container) {
118  specific_attr_begin<SpecificAttr>(container);
119  if (i != specific_attr_end<SpecificAttr>(container))
120  return *i;
121  else
122  return nullptr;
123 }
124 
125 } // namespace clang
126 
127 #endif // LLVM_CLANG_AST_ATTRITERATOR_H
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
__PTRDIFF_TYPE__ ptrdiff_t
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Definition: AttrIterator.h:33
friend bool operator!=(specific_attr_iterator Left, specific_attr_iterator Right)
Definition: AttrIterator.h:93
reference operator*() const
Definition: AttrIterator.h:65
std::ptrdiff_t difference_type
Definition: AttrIterator.h:60
std::forward_iterator_tag iterator_category
Definition: AttrIterator.h:59
friend bool operator==(specific_attr_iterator Left, specific_attr_iterator Right)
Definition: AttrIterator.h:84
specific_attr_iterator & operator++()
Definition: AttrIterator.h:74
specific_attr_iterator operator++(int)
Definition: AttrIterator.h:78
The JSON file list parser is used to communicate input to InstallAPI.
bool hasSpecificAttr(const Container &container)
Definition: AttrIterator.h:111
SpecificAttr * getSpecificAttr(const Container &container)
Definition: AttrIterator.h:116
specific_attr_iterator< SpecificAttr, Container > specific_attr_end(const Container &container)
Definition: AttrIterator.h:106
specific_attr_iterator< SpecificAttr, Container > specific_attr_begin(const Container &container)
Definition: AttrIterator.h:101